1

我的问题是关于 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 函数是对象?另一个问题由此而来。该 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

为什么使用“这个”不起作用?

最后一个问题,使用关键字“new”和“createObject”有什么区别。Douglas Crokford 在他的书中建议使用“CreateObject”,但我不明白为什么。谢谢大家的意见

4

2 回答 2

5

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

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

2. 函数也是对象

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


我希望以上两个主题都能帮助您了解函数的工作原理。至于你的最后一个问题:CrockfordcreateObject是一种实现继承的不同方式,基本上是Object.create在符合 ES5 的浏览器中做的。它允许一个对象直接从另一个对象继承,而不需要您手动创建一个新的构造函数,设置它的prototype属性(这是一个函数对象的属性示例),并使用new. Crockford 更喜欢这一点,并表示他不再使用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

函数的一个非常重要的默认属性是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

...除非您故意返回其他内容:

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(),因为它可以访问其构造函数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
于 2013-06-19T20:24:55.433 回答
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 代码。'新'是。

于 2013-06-19T20:39:09.187 回答