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

不理解在Javascript中使用新关键字,javascript,prototype,new-operator,Javascript,Prototype,New Operator,下面的代码片段来自O'Reilly的“Javascript Web应用程序”。在这篇文章中,作者解释说,使用new关键字通常会返回此上下文,除非您专门返回其他内容——以下是他返回的“将建立新类的函数”(第7页): 我不明白。klass在这里做什么?在var Person=new Class的情况下,我得到的不是一个新的类对象,而是一些可以创建类的函数吗?这就是我从课文中读到的,但我很困惑 在javascript中,new关键字隐式返回this 当您拥有函数Foo(){}并应用新Foo时,在引擎盖

下面的代码片段来自O'Reilly的“Javascript Web应用程序”。在这篇文章中,作者解释说,使用
new
关键字通常会返回
上下文,除非您专门返回其他内容——以下是他返回的“将建立新类的函数”(第7页):


我不明白。klass在这里做什么?在
var Person=new Class
的情况下,我得到的不是一个新的类对象,而是一些可以创建类的函数吗?这就是我从课文中读到的,但我很困惑

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

当您拥有
函数Foo(){}
并应用
新Foo
时,在引擎盖下javascript执行此
函数Foo(){返回此;}
。他通过显式返回一个不同的对象(klass对象),覆盖了javascript的
new
的工作方式

看看这个例子

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
变量(指针)中。

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

此通常可以指向三个方面。 如果您有一个作为对象属性的函数:

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

Bob.say(); // "Bob"
在本例中,
this
指向拥有该属性的任何对象(前面一点的任何对象,在调用函数的确切时刻)

因此,
这个
是在最后一秒决定的

函数也有自己的属性,如对象。
其中有两个函数名为
.call
.apply
,它们允许您运行函数,但可以准确地告诉函数这是什么

记住如何
say()无法单独工作

var say = Bob.say;
say.call(Bob); // "Bob" -- hooray!
的下一部分是我们在面向对象语言中最常用的部分;使用
this
new
创建类的新实例:

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

var bob = new Person("Bob");
bob.say(); // "Bob"
基本上,在这个构造函数(或任何函数,因为构造函数在JS中并不特殊)内部,函数首先检查是否调用了
new

如果是,则将此
设置为全新对象,无论它是否是对象的一部分:

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

如果您使用的函数中,
不是对象(通过调用/应用,或作为对象的属性),并且未使用
新建
创建新对象,则
指向
窗口

这就是为什么
say()在之前无法单独工作<代码>窗口。说()是等效的

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

var bob = new Person();
bob instanceof Person;  // true
它还允许从该构造函数生成的对象访问所有实例共享的
prototype
对象

现在,看看班级里发生了什么:
我们正在创建一个
新类()对象。
函数中,
this={}(因为
新的
)。
然后,我们正在创建一个新的“构造函数”函数,
klass

然后,我们正在设置原型化的
init
函数,我们
将其应用于任何新的
this
(在
klass
中,调用新实例时)

那我们就把klass还给你

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

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


希望这对
new
this
有所帮助。请按照作者的逻辑调用
Class/klass

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

如果他/她是正确的,则输入以下代码:

var Class = function(){
    var klass = function(){
        this.init.apply(this, arguments);
    };
    klass.prototype.init = function(){};
    return klass;
};
不定义“类”类;相反,它定义了一个“基”,当
new
ed时,它将返回一个私有定义的类,而不是返回一个实例,当
new
ed时,它将保证运行
init()
方法(
this.init.apply(this)

以这种方式,当

var Person = new Class;
您正在创建一个名为
Person
的新类,该类遵循
类中定义为
klass
的约束和行为(如果有)(有点像“真实”OOP中的
扩展
/
继承

所以下面的代码

Person.prototype.init = function(){
// Called on Person instantiation
};
实际上是为类定义一个“构造函数”

编辑

对不起,昨天没有写出合适的单词和句子。我不善于表达

如果您熟悉OOP,您可以想象,
是一个接口/抽象/虚拟类,当您
新建类
时,您不是在创建实例,而是在扩展/继承/实现
中私下/虚拟定义的行为


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

实际上,这里
var Person=new Class
new
关键字仅用于启动
Class
函数,因此基本上您可以像这样使用
var Person
var Person = new Class;
Person.prototype.init = function(){
// Called on Person instantiation
};