不了解在Javascript中使用新关键字

lar*_*ryq 6 javascript prototype new-operator

下面的代码片段来自O'Reilly的"Javascript Web Applications".在其中,作者解释说使用new关键字通常会返回一个this上下文,除非你特别返回其他内容 - 在下面,他将返回'一个设置新类的函数',用他的话来说(第7页):

var Class = function(){
    var klass = function(){
        this.init.apply(this, arguments);
    };
    klass.prototype.init = function(){};
    return klass;
};

var Person = new Class;

Person.prototype.init = function(){
    // Called on Person instantiation
};

// Usage:
var person = new Person;
Run Code Online (Sandbox Code Playgroud)

我不跟这个.回来klass做什么?在var Person = new Class我的情况下,我没有得到一个新的Class对象,而是一些可以创建一个类的函数?这就是我从文中读到的内容,但这让我感到困惑.

Nor*_*ard 6

在他到达目的地之前,第一步是获得this.

this通常可以指出三件事.如果你有一个函数,它是一个对象的属性:

var Bob = {
    name : "Bob",
    say  : function () { console.log(this.name); }
};

Bob.say(); // "Bob"
Run Code Online (Sandbox Code Playgroud)

在这种情况下,this指向拥有该属性的任何对象(无论前面是一个点,在调用该函数的确切时刻)

var say = Bob.say; // passing the function to a variable
var Sam = { name : "Sam" };
Sam.say = Bob.say; // passing the function to an object's property

say(); // undefined -- not what you were expecting
Sam.say(); // "Sam"
Run Code Online (Sandbox Code Playgroud)

所以this在最后一秒确定.

函数也具有自己的属性,如对象.
其中两个是函数调用.call,并.apply和他们允许您运行的功能,但告诉函数到底是什么this是.

还记得自己怎么say();没有工作?

var say = Bob.say;
say.call(Bob); // "Bob" -- hooray!
Run Code Online (Sandbox Code Playgroud)

下一部分this是我们在面向对象语言中最常用的部分; 使用this连同new使一个类的新实例:

var Person = function (name) {
    this.name = name;
    this.say = function () { console.log(this.name); };
};

var bob = new Person("Bob");
bob.say(); // "Bob"
Run Code Online (Sandbox Code Playgroud)

基本上,在这个构造函数内部(或任何函数,因为构造函数在JS中并不特殊),该函数首先检查是否new被调用.
如果是,则设置this为全新对象,无论它是否是对象的一部分:

var Creatures = {};
Creatures.Person = Person;

Creatures.Person("Bob"); // `this` === Creatures
Creatures.name; // "Bob" -- whoops
var bob = new Creatures.Person("Bob");
bob.say(); // "Bob", yay!
Run Code Online (Sandbox Code Playgroud)

所以就像函数在函数if (new) { this = {}; }顶部说的那样.

我说有三种可能性.
第三个是this === window
如果你使用的函数this不是一个对象(通过调用/应用,或作为一个对象的属性)并且new不用于创建一个新对象,那么this指向window.
这就是为什么say();之前没有独立工作的原因; window.say();是等价的.

回到new一秒钟 - new做其他几件事.
即,它设置对象的构造函数的值:

var bob = new Person();
bob instanceof Person;  // true
Run Code Online (Sandbox Code Playgroud)

它还为由该构造函数构成的prototype对象提供对所有实例共享的对象的访问权限.

现在,看看Class/Klass里面发生了什么:
我们正在创建一个new Class();对象.
Class函数内部,this = {};(因为new).
然后,我们正在创建一个新的"构造函数"函数klass.

然后,我们将设置原型init函数,我们将它们设置.apply为任何新函数this(在klass调用新实例时).

然后我们回到了klass.

klass实际上是你在创建一个新类时所要调用的

当你调用一个类的新对象时,正在运行klass.

希望与帮助newthis.callClass/klass.