7

下面的代码片段来自 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;

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

4

4 回答 4

7

在到达他要去的地方之前,第一步是得到this

通常可以指出三件事this。如果您有一个作为对象属性的函数:

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

Bob.say(); // "Bob"

在这种情况下,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"

所以this在最后可能的一秒决定。

函数也有它们自己的属性,比如对象。
其中两个是被调用的函数.call.apply它们允许你运行函数,但告诉函数究竟是什么this

还记得自己如何say();不工作吗?

var say = Bob.say;
say.call(Bob); // "Bob" -- hooray!

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

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

var bob = new Person("Bob");
bob.say(); // "Bob"

基本上,在这个构造函数(或任何函数,因为构造函数在 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!

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

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

回到new一秒钟——new做一些其他的事情。
即,它设置对象的构造函数的值:

var bob = new Person();
bob instanceof Person;  // true

它还使由该构造函数生成的prototype对象可以访问所有实例共享的对象。

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

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

然后我们要归还克拉斯。

klass 实际上是您创建新课程时所调用的内容

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

希望对newandthis.calland有帮助Class/klass

于 2013-01-14T07:45:17.693 回答
3

在 javascript 中,new关键字隐式返回this

当您拥有function Foo () {}并申请new Foo时,在后台 javascript 会执行此操作function Foo () { return this; }new他通过显式返回一个不同的对象(klass 对象)来覆盖 javascript 的工作方式。

看看这个例子。

function Foo () { this.name = "foo"; };

function Bar () {
    return new Foo; 
};

var bar = new Bar;  // bar is now a Foo, because of the explicit return.

bar.name //=> 'foo'

如果你能遵循这一点,你就可以遵循他正在做的事情。

当您说var Person = new Class时,它实际上是返回klass函数并将其存储在Person变量(指针)中。

于 2013-01-14T07:41:38.070 回答
1

按照作者的逻辑:

使用new关键字通常会返回this上下文, 除非您特别返回其他内容

如果他/她是正确的,那么下面的代码:

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

不定义“类”类;相反,它定义了一个“基础”,当newed 时,而不是返回实例,将返回一个私有定义的,当newed 时,将保证运行init()方法 ( this.init.apply(this))。

这样一来,当

var Person = new Class;

您正在创建一个名为的新Person,它遵循定义为klass内部的约束和行为(如果有) Class(有点像extend/inherit在“真实”OOP 中)。

所以下面的代码

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

实际上是为class Person定义一个“构造函数” 。

编辑

很抱歉昨天没有想出正确的单词和句子。我不善于表达。

如果您对 OOP 感到满意,您可以想象Class是一个接口/抽象/虚拟类,当您new Class而不是创建实例时,您是在扩展/继承/实现私有/虚拟定义的行为Class

klass.prototype.init=function(){};有点像 JS 的抽象/虚函数方式,通过组合,this.init.apply(this)你可以在可能的层面上想象它是一个构造函数。

于 2013-01-14T07:47:30.560 回答
0

实际上,这里var Person = new Class;new关键字只是用来触发Class函数的,所以基本上你可以这样使用var Person = Class();它会得到相同的结果

于 2017-01-13T15:08:24.390 回答