领会JavaScript的原型属性

2016/06/21 · JavaScript
· 2 评论 ·
原型

本文由 伯乐在线 –
alvendarthy
翻译,sunshinebuel
校稿。未经许可,禁绝转发!
德语出处:bytearcher。应接参加翻译组。

理解 JavaScript
prototype天性不太轻松。你大概知道它同面向对象编制程序(OOP)和目的世袭有关,但不一定对其技能原理非常通晓。

1.原型三回九转

  面向对象编程可以透过重重渠道实现。别的的言语,比方Java,使用基于类的模子达成: 类及对象实例分化对待。但在 JavaScript
中绝非类的概念,取代他的是全方位皆对象。JavaScript
中的世襲通过原型世襲达成:三个目的直接从另一指标世襲。对象中包罗其接二连三系列中祖先的援引——对象的
prototype 属性。

第一是在拜候上的界别,当访谈实例对象的某部属性但它自己没有的时候,它就能够到原型中去搜寻,但不会去搜寻静态属性。

JavaScript中是未曾类的概念的,有的只是原型和对象。

原型的意思是指:若是布局器有个原型对象A,则由该布局器创制的实例(Object
Instance卡塔尔(英语:State of Qatar)都自然复制于A。““在JavaScript中,对象实例(Object
Instance卡塔尔国并不曾原型,而结构器(Constructor卡塔尔国有原型,属性'<布局器>.prototype’指向原型。对象独有“构造自有些原型”的主题素材,并不设有“持有(或持有)有个别原型”的标题。

原型世袭

面向对象编制程序能够通过重重门路完成。其他的言语,例如Java,使用基于类的模子落成: 类及对象实例分化对待。但在 JavaScript
中绝非类的概念,取代他的是全方位皆对象。JavaScript
中的世袭通过原型世袭实现:叁个目的间接从另一指标世襲。对象中包涵其持续类别中祖先的援引——对象的 prototype 属性。

class 关键字是在 ES6 中第叁回引进 JavaScript
的。其实,它并未为面向对象世襲引进新模型, class
关键字通过语法糖,达成了本文介绍的原型本性和结构函数。

2. JavaScript 达成持续的言语特色

  • 当尝试访问 JavaScript
    对象中一纸空文的属性时,分析器会查找相配的靶子原型。举个例子调用
    car.toString(卡塔尔(英语:State of Qatar),假设 car 没有 toString 方法,就能调用 car
    对象的原型。 那一个查找进度会平昔递归,
    直到寻觅到十三分的原型也许世襲链尽头。

  • 调用  new Car(卡塔尔(قطر‎会创立一个新的靶子,并伊始化为 Car.prototype。
    那样就允许为新目的设置原型链。需求介意的是,new Car(卡塔尔 唯有当  Car 是函数时才有含义。
    此类函数即所谓布局函数

  • 调用对象的二个分子函数时, this
    的值被绑定为当下指标。比如调用 “abc”.toString(卡塔尔(英语:State of Qatar),this 的值被安装为
    “abc”,然后调用 toString 函数。该技艺扶助代码重用:同样的代码,可在
    this
    为各类区别的值时调用。对象的积极分子函数,也被称之为对象的主意。

   图片 1

  首先,大家定义布局函数 Rectangle。
依据标准,大家大写布局函数名首字母,申明它能够用 new
调用,以示与别的常规函数的界别。构造函数自动将 this
赋值为生机勃勃空对象,然后代码中用 x 和 y 属性填充它,以备后用。然后,
Rectangle.prototype 新扩展三个透过 x 和 y 属性总结周长成员函数。 注意 this
的接受,在不一样的对象中,this
会有两样的值,那个代码都得以符合规律干活。最终, 多少个名叫 rect
的靶子创制出来了。 它继续了 Rectangle.prototype, 大家得以调用
rect.perimeter(卡塔尔国, 然后将结果打字与印刷到调整台。

// 实例对象不会去查找静态属性
function Foo(){}
Foo.a = 1;
var foo = new Foo();
foo.a // undefined

// 当实例对象没有某个属性时,会尝试去原型中查找
function Foo(){}
Foo.prototype.a = 1;
var foo = new Foo();
foo.a // 1

在说原型早前先说说JavaScript中目的的三连串型:

 

JavaScript 达成持续的言语特色

以下语言特征合营促成了 JavaScript 世袭。

  • 当尝试访问 JavaScript
    对象中官样文章的性质时,深入分析器会查找相配的目的原型。举例调用 car.toString(),如果
    car 没有 toString 方法,就能够调用 car 对象的原型。
    这一个查找进度会一贯递归, 直到搜索到十三分的原型也许世襲链尽头。
  • 调用  new Car() 会创造三个新的靶子,并初步化为 Car.prototype
    这样就允许为新对象设置原型链。要求专一的是,new Car()
    只有当  Car 是函数时才有意义。 此类函数即所谓布局函数。
  • 调用对象的三个成员函数时, this
    的值被绑定为当下目的。比如调用 "abc".toString()this
    的值被设置为 "abc",然后调用 toString
    函数。该本领帮助代码重用:一样的代码,可在 this
    为各类分歧的值时调用。对象的成员函数,也被堪当对象的艺术。

prototype 属性名称带来的误解

  有局地有关 JavaScript 的原型的误解。
多少个对象的原型与对象的 prototype 属性实际不是一次事。
后面一个用于在原型链中相配一纸空文的质量。后面一个用于通过 new
关键字成立对象,它将用作新创建对象的原型。
明白二者的间隔,将扶植你到底领略 JavaScript 中的原型天性。

  Rectangle.prototype 是用 new
Rectangle(卡塔尔(英语:State of Qatar) 创设出来指标的原型, 而 Rectangle 的原型实际上是 JavaScript
的 Function.prototype。(子对象的原型是父对象的 prototype 属性
对象中保留原型的变量,也被喻为内部原型援用(the internal prototype
link),历史上也曾称之为 __proto__ ,对那个名号始终存在有的争论。
更可相信的,它能够被称呼 Object.getPrototypeOf(…卡塔尔 的重临值。

静态方法中的this指向调用它的对象,比方在底下代码中针对的就是调用它的Foo,原型方法中的this指向实例对象

(1)客商制造的对象,也便是用new关键字创造出来的指标。如:

三个自定义的函数,假使为

举个栗子

咱俩用面向对象编制程序,达成一个划算矩形周长的例证。

JavaScript

function Rectangle(x, y) { this.x = x; this.y = y; }
Rectangle.prototype.perimeter = function() { return 2 * (this.x +
this.y); } var rect = new Rectangle(1, 2);
console.log(rect.perimeter()); // outputs ‘6’

1
2
3
4
5
6
7
8
9
10
11
function Rectangle(x, y) {
    this.x = x;
    this.y = y;
}
 
Rectangle.prototype.perimeter = function() {
    return 2 * (this.x + this.y);
}
 
var rect = new Rectangle(1, 2);
console.log(rect.perimeter()); // outputs ‘6’

第豆蔻梢头,大家定义布局函数 Rectangle
遵照规范,大家大写构造函数名首字母,申明它能够用 new
调用,以示与此外常规函数的区别。布局函数自动将 this
赋值为风流倜傥空对象,然后代码中用 xy 属性填充它,以备后用。

然后, Rectangle.prototype 新扩充一个经过 xy
属性总计周长成员函数。 注意 this 的运用,在差异的对象中,this
会有例外的值,这个代码都能够健康职业。

最终, 三个名叫 rect 的靶子创制出来了。
它继续了 Rectangle.prototype, 我们可以调用 rect.perimeter()
然后将结果打字与印刷到调整台。

function Foo(){}
Foo.fn = function(){
    console.log(this);
};
Foo.prototype.fn = function(){
    console.log(this);
};
var foo = new Foo();
foo.fn(); // Foo {}
Foo.fn(); // function Foo(){}

         var obj = new Object();

function Person(){
}

prototype 属性名称带给的误解

有部分关于 JavaScript 的原型的误会。
贰个指标的原型与目的的 prototype 属性并非一回事。
后边贰个用于在原型链中相称不设有的性质。后面一个用于通过 new
关键字创造对象,它将用作新创设对象的原型。
领会二者的分化,将扶持你到底领略 JavaScript 中的原型天性。

在大家的例证中, Rectangle.prototype 是用 new Rectangle()
创立出来目的的原型, 而 Rectangle 的原型实际上是 JavaScript
的 Function.prototype。(子对象的原型是父对象的 prototype 属性)

目的中保留原型的变量,也被称之为内部原型援引(the internal prototype
link
),历史上也曾称之为 __proto__ ,对这么些称谓始终存在部分争辩。
更标准的,它能够被号称 Object.getPrototypeOf(...) 的重回值。

2 赞 5 收藏 2
评论

静态属性和原型属性的区分就在于this的照准以至查找准绳上,但this的指向性难题并非最关键的,拿完结链式调用来讲

(2)布局函数(其实在JavaScript中其它非无名函数都得以是布局函数)对象。如下面的Object正是个结构函数对象。

当使用 new
创造对象时,创立的对象实际是对Person原型的贰个援用。如下列代码:

关于小编:alvendarthy

图片 2

叁个热爱生活的玩意!
个人主页 ·
作者的稿子 ·
16

图片 3

// 通过原型实现链式调用
function Foo(){}
Foo.prototype.a = function(){
    console.log('a');
    return this;
};
Foo.prototype.b = function(){
    console.log('b');
    return this;
};
var foo = new Foo();
foo.a().b(); // a b

// 通过静态方法实现链式调用
function Foo(){}
Foo.a = function(){
    console.log('a');
    return this;
};
Foo.b = function(){
    console.log('b');
    return this;
};
Foo.a().b(); // a b

(3)原型对象。布局函数的prototype属性所指向的靶子。

<script type="text/javascript" >

       function Person(){

       }

       function Person2(){
       }
        var a= new Person();
       Person2.prototype=new Person;

       var b=new Person2();
       var c=new Person2();

       alert(b instanceof Person);

</script>

最大的分别还是在查究准则上,在原型上增添属性能够视作私下认可属性来使用

上边三类对象的__proto__特性所指向的目的即为该对象的原型,也对应当对象的构造函数的prototype属性。Function.prototype是持有函数的原型,Object.prototype是独具目的的祖宗。因为Object是叁个布局函数,全部Object.__proto__

Function.prototype。又因为Function.prototype是一个对象(原型对象),所以Function.prototype.__proto__
= Object.prototype。而Function.__proto__ =
Function.prototype。因为Object.prototype是具备目的的古代人所以有Object.prototype.__proto__
= null。此外原型对象中还会有一个照准布局函数的性质constuctor。拿Function
和 Object那三个布局函数为例,它们的原型属性Function.prototype 和
Object.prototype
中都有叁个constructor属性。个中Function.prototype.constructor =
Function, Object.prototype.constructor = Object。

下边用二个例子来注明:

 function func(){ };

 var f = new func();

console.log( f.__proto__ == func.prototype); // true

console.log( f.__proto__.__proto__ == Object.prototype); //true

console.log( func.__proto__ == Function.prototype); // true

console.log( func.prototype.__proto__ == Object.prototype); //true

console.log( func.prototype.constructor == func); //true

console.log( Object.__proto__ == Function.prototype); //true

console.log( Object.property.__proto__ == null); //true

   
 在那代码中,我们设定了Person2的原型为Person的贰个目的,然后创立了Person2的对象b
,然后 输出b instanceof Persontrue。(instanceof
是js的语法,用于相比较对象是或不是为某些项目
)

function Foo(){}
Foo.prototype.a = 1;
var foo = new Foo(),
    foo2 = new Foo();
foo2.a = 2;
foo.a // 1
foo2.a // 2

 

每一个实例对象都足以有所和煦的品质和章程,在未有设置的意况下才会去品味利用prototype上的习性和艺术,而静态方法是爱莫能助落到实处这种效果的。

 

    此为截图:

       图片 4

 

 

       这里有生机勃勃篇较为详细的介绍:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图