不理解在Javascript中使用新关键字
下面的代码片段来自O'Reilly的“Javascript Web应用程序”。在这篇文章中,作者解释说,使用不理解在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时,在引擎盖
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
};