像其他高级语言一样,javascript也有一个新的关键字。我们曾经知道new是用来创建一个类的实例对象的,但是js中的一切都是对象,那么为什么需要new关键字呢?事实上,js中的new关键字不是用来创建类的实例对象,而是用来继承的。接下来,本文将带您探索JS中新的奥秘。
函数Animal(name){ this . name=name;} Animal.color=' blackanimal . prototype . say=function(){ console . log(' I ' is this . name);};var cat=新动物(“猫”);console.log(cat.name,//cat . height//undefined);cat . say();//我是catconsole.log(Animal.name,//Animal . color//back);animal . say();//Animal.say不是函数。如果你能理解上面的输出,就意味着你已经非常了解new和这个在js中的运行机制。请忽略这篇文章!
我们将通过分析这个例子来加深你对js中new和继承的理解!【如果你对js不了解,请先阅读:JS范围和这个关键词】
一、代码解释。
第1-3行创建了一个函数Animal,并定义了属性:name,名称在此。name的值是执行函数时的参数。
第四行在Animal对象上定义了一个静态属性: color(Animal本身是一个函数对象),并赋值为“black”。
第5-7行在Animal函数的原型对象原型上定义了一个say()方法,say方法输出该方法的名称值。
第8行通过new关键字创建一个新的对象猫。
10-14行cat对象尝试访问名称和颜色属性,并调用say方法。
16-20行动物对象尝试访问名称和颜色属性,并调用say方法。
二、重点分析。
第八行代码是关键:
var cat=新动物(“猫”);JS引擎在执行这段代码的时候做了大量的工作,用伪代码模拟了它的工作流程如下:
var obj={ };物体。__原型_ _ _=动物.原型;var结果=Animal.call(obj,‘cat’);返回结果类型==='obj '?结果: obj(1)创建一个空对象obj
(2)将对象的原型指向动物的原型,建立对象对象的原型链:对象-动物。原型-对象。原型-空。
【如果不了解JS原型链,请先阅读JS原型和原型链】
(3)在obj对象的执行空间调用Animal函数,传递参数“cat”。相当于var结果=obj。动物(“猫”)。
当这个句子被执行时,obj生成属性名并将其指定为“cat”。【请阅读JS中调用的用法:JS中的调用和应用】
(4)检查步骤3返回的返回值,如果没有返回值或者返回非对象值,则将obj作为新对象返回;否则,返回值将作为新对象返回。
在了解new的运行机制后,我们知道cat实际上是流程(4)的返回值,因此我们对cat对象的了解更多:
猫的原型是动物。原型-对象。原型-空。
猫身上有了新的属性:名字。
分析完cat的生成过程,我们再来看看输出:
cat . name-在过程(3)中,obj对象生成name属性。因此,猫名是这里的obj.name。
cat . color-猫会先寻找自己的颜色,如果没有找到,就会沿着原型链寻找。在上面的例子中,我们只在Animal对象上定义了颜色,而没有在它的原型链上定义,所以我们找不到它。
Cat.say-cat首先会找到自己的say方法,如果没有找到,就会沿着原型链找到。在上面的例子中,我们在《动物》的原型上定义了say,所以我们在原型链上找到了say方法。
此外,this.name也在say方法中访问,这里指的是它的调用者obj,所以输出是obj.name的值
对于Animal来说,它也是一个对象,所以在访问属性和方法时也遵守上面的搜索规则,所以:
动物。颜色——“黑色”
动物名称——“动物”,动物首先搜索自己的名字,然后找到它。注意:但是这个名字不是我们定义的名字,而是函数对象的一个内置属性。
一般来说,当生成一个函数对象时,名字属性是内置的,函数名被当作赋值(只有函数对象)。
动物说-动物本身不会找到说的方法,但会沿着原型链查找。动物的原型链是什么?
根据调试结果,动物原型链如下:
动物-功能.原型-对象.原型-空
因此,在Animal的原型链中没有定义say方法!
综上所述,javascript的new关键字的主要功能是继承。在上面的例子中,当生成cat对象时,它继承了在Animal中定义的方法和属性,所以cat不是Animal的一个实例,而是它的子类(松散地说)。有些人可能还会想:既然猫是新来的,猫和动物应该是同一类型的。我觉得既然是父类和子类的关系,就不可能是同一类型。如果你不相信,看:
使用新关键字的javascript的差异。
第一种方法使用new关键字以原型方式向窗口对象公开用户对象。
//onevar user=function(){ this . name=' ';this.id=};user . add=function(){ console . log(' add ');};user . delete=function(){ console . log(' delete ');};user.prototype=用户;window . user=new user();在第二种方式中,用户对象直接暴露给窗口对象,而不使用新的关键字。
//twovar user={ name: ' ',id : ' ' };user . add=function(){ console . log(' add ');};user . delete=function(){ console . log(' delete ');};window.user=用户;使用
button onclick=' user . add()' add/button button onclick=' user . delete()' delete/button。