我的问题是关于javascript中的函数和对象。我有三个问题源于彼此。在下面的例子中,我尝试在测试中访问'a'的值,但是我得到了未定义。但我创建了一个新的测试对象,然后我可以访问'a'值并更改它。
//create a function called test
var test=function() {
this.a=2
this.b=3 };
test.a//undefined
//create a object called test1 using 'new'
test1 = new test();
test1.a//2
//change the value of a in test1
test1.a=4
test1 //Object { a=4, b=3}
在尝试找到这种情况发生的原因时,我遇到了这个javascript functions are objects?,另外一个问题突然出现了。 该SO问题的公认解决方案如下:
var addn = function func(a) {
return func.n + a;
};
addn['n'] = 3;
addn(3);
我将'func.n'更改为'this'并且它不再有效
var addn=function func(a) {
return this.n+a;
};
addn['n']=3;
addn(3); //NaN
使用'this'制作匿名函数也无济于事
//anonymous function
var addn=function(a) {
return this.n+a;
};
addn['n']=3;
addn(3); //NaN
为什么使用'this'不起作用?
最后一个问题,使用关键字'new'和'createObject'有什么不同。道格拉斯·克罗克福德建议在他的书中使用“CreateObject”,但我不明白为什么。谢谢大家的意见
答案 0 :(得分:5)
当你调用new FuncName
时,该函数充当构造函数,并且this
内部的值指向正在构造的对象(而不是函数本身)。当您移除new
时,this
变为undefined
,退回到全局对象(除非您处于严格模式)。
每个函数都是Function
的一个实例,因此函数本身就是对象,并且可以拥有自己的属性。只能使用this.propName
在函数体内使用funcName.propName
访问这些属性。那是因为函数中的this
永远不会函数对象本身(除非你强制它,bind
,call
或apply
)。
我希望上面的两个主题可以帮助您了解函数的工作原理。至于你的最后一个问题:Crockford的createObject
是一种实现继承的不同方式,基本上完成了Object.create
在ES5兼容浏览器中的作用。它允许对象直接从另一个对象继承,而不需要手动创建新构造函数,设置其prototype
属性(这是函数对象上属性的一个示例),并使用{{创建一个实例1}}。克罗克福德更喜欢这样,并说他不再使用new
来支持这种做法。
在回答您在聊天中提出的问题时,我们试图通过示例来解释哪些功能是什么以及它们做了什么。
你打电话给他们,他们会做点什么:
new
您也可以传递它们的值,并让它们返回值
function alertThis(what) {
alert(what)
}
alertThis("alerting something");
可以传递它们并返回任何,包括对象......
function timesTwo(num) {
return num * 2;
}
timesTwo(2); // 4
......和其他功能:
function createPerson(firstName, lastName) {
return {
firstName : firstName,
lastName : lastName
}
}
var john = createPerson('John', 'Doe');
john.lastName; // "Doe"
函数可以像任何普通对象一样传递和返回。那是因为他们是对象。像任何对象一样,它们可以具有属性:
function timesN(n) {
return function(num) {
return n * num;
}
}
var timesThree = timesN(3);
timesThree(5); // 15
函数的一个非常重要的默认属性是function countCalls() {
countCalls.timesCalled++;
}
countCalls.timesCalled = 0;
countCalls();
countCalls();
countCalls.timesCalled; // 2
。这是一个特殊的财产,我们会明白为什么。
函数可以像常规OO语言中的类构造函数一样运行。 使用prototype
进行调用时,会创建某个“类”的新对象。这个新对象在函数内部被称为new
,并自动返回:
this
......除非你刻意回复别的东西:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
var john = new Person('John', 'Doe');
john.firstName; // "John"
john instanceof Person; // true
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
var fakePerson = {
firstName : firstName,
lastName : lastName
};
return fakePerson;
}
var notPerson = new Person('John', 'Doe');
notPerson.firstName; // "John"
notPerson instanceof Person; // false
// Note: the object called 'this' inside the function is created, but
// after the function is called there is no outside reference to it.
属性回到真人:
prototype
对象function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Add something to the Person prototype
Person.prototype.sayHi = function() {
return "hi, I'm " + this.firstName;
}
var john = new Person('John', 'Doe');
john.sayHi(); // "Hi, I'm John"
john.constructor; // Person
可以john
,因为它可以访问构造函数sayHi()
属性中的所有内容。但它无法直接看到Person的其他属性(仅通过自己的prototype
属性):
constructor
答案 1 :(得分:0)
1。 addn ['n'] = 3; //表示将静态属性n添加到函数(对象)addn。 所以addn.n也可以工作。
2 this.n表示实例的属性n。 this.n === undefined所以它返回NaN。
3 var addn = function func(a)表示为func指定第二个名称。 在大多数情况下,var addn = function(a)是更好的格式。
4 createObject不是本机javaScript代码。 '新'是。