使用关键字“this”的javascript函数和对象不起作用

时间:2013-06-19 20:21:04

标签: 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}

在尝试找到这种情况发生的原因时,我遇到了这个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”,但我不明白为什么。谢谢大家的意见

2 个答案:

答案 0 :(得分:5)

1。函数是新对象的构造函数

当你调用new FuncName时,该函数充当构造函数,并且this内部的值指向正在构造的对象(而不是函数本身)。当您移除new时,this变为undefined,退回到全局对象(除非您处于严格模式)。

2。函数也是对象

每个函数都是Function的一个实例,因此函数本身就是对象,并且可以拥有自己的属性。只能使用this.propName在函数体内使用funcName.propName访问这些属性。那是因为函数中的this 永远不会函数对象本身(除非你强制它,bindcallapply )。


我希望上面的两个主题可以帮助您了解函数的工作原理。至于你的最后一个问题: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代码。 '新'是。