bra*_*orm 1 javascript function object this
我的问题是关于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}
Run Code Online (Sandbox Code Playgroud)
在试图找到为什么会发生这种情况时,我遇到了这个javascript函数是对象吗?另外一个问题突然出现了.该SO问题的公认解决方案如下
var addn = function func(a) {
return func.n + a;
};
addn['n'] = 3;
addn(3);
Run Code Online (Sandbox Code Playgroud)
我将'func.n'更改为'this',它不再有效
var addn=function func(a) {
return this.n+a;
};
addn['n']=3;
addn(3); //NaN
Run Code Online (Sandbox Code Playgroud)
用'this'制作匿名函数也没有用
//anonymous function
var addn=function(a) {
return this.n+a;
};
addn['n']=3;
addn(3); //NaN
Run Code Online (Sandbox Code Playgroud)
为什么使用'this'不起作用?
最后一个问题,使用关键字'new'和'createObject'有什么不同.道格拉斯·克罗克福德建议在他的书中使用"CreateObject",但我不明白为什么.谢谢大家的意见
当你调用时new FuncName,函数充当构造函数,而thisinside 的值指向正在构造的对象(而不是函数本身).当你删除new,this变成undefined,回落到全局对象时(除非你处于严格模式).
每个函数都是一个实例Function,因此函数本身就是对象,并且可以拥有自己的属性.这些属性不能this.propName在函数体内部访问,只能使用funcName.propName.这是因为this里面的功能是从来没有的功能对象本身(除非你强迫它是与bind,call或apply).
我希望上面的两个主题可以帮助您理解函数的工作原理 至于你的最后一个问题:Crockford createObject是一种实现继承的不同方式,基本上Object.create与ES5兼容的浏览器有关.它允许对象直接从另一个对象继承,而不需要手动创建新的构造函数,设置其prototype属性(这是函数对象上的属性的示例),并使用创建实例new.克罗克福德更喜欢这样,并表示他不再new支持这种做法了.
在回答您在聊天中提出的问题时,我们试图通过示例解释哪些功能是什么以及它们做了什么.
你打电话给他们,他们做了一些事:
function alertThis(what) {
alert(what)
}
alertThis("alerting something");
Run Code Online (Sandbox Code Playgroud)
您还可以传递它们的值,并让它们返回值
function timesTwo(num) {
return num * 2;
}
timesTwo(2); // 4
Run Code Online (Sandbox Code Playgroud)
它们可以传递并返回任何东西,包括对象......
function createPerson(firstName, lastName) {
return {
firstName : firstName,
lastName : lastName
}
}
var john = createPerson('John', 'Doe');
john.lastName; // "Doe"
Run Code Online (Sandbox Code Playgroud)
......和其他功能:
function timesN(n) {
return function(num) {
return n * num;
}
}
var timesThree = timesN(3);
timesThree(5); // 15
Run Code Online (Sandbox Code Playgroud)
函数可以像任何普通对象一样传递和返回.那是因为它们是对象.像任何对象一样,它们可以具有属性:
function countCalls() {
countCalls.timesCalled++;
}
countCalls.timesCalled = 0;
countCalls();
countCalls();
countCalls.timesCalled; // 2
Run Code Online (Sandbox Code Playgroud)
函数的一个非常重要的默认属性是prototype.这是一个特殊的财产,我们会明白为什么.
函数可以像常规OO语言中的类构造函数一样运行.当调用时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
Run Code Online (Sandbox Code Playgroud)
......除非你刻意回复别的东西:
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.
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
该对象john可以sayHi()因为它可以访问其构造函数prototype属性中的所有内容.但它不能直接看到Person的其他属性(只能通过自己的constructor属性):
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
Person.timesCalled++;
// There is no 'this.timesCalled', only Person.timesCalled
}
Person.timesCalled = 0;
var john = new Person('John', 'Doe');
john.timesCalled; // undefined - john cannot be called, Person can
john.constructor.timesCalled; // 1
Run Code Online (Sandbox Code Playgroud)