JS主题类别:浅谈 原型对象和原型链

2016/03/01 · JavaScript
· 2 评论 ·
原型对象,
原型链

原稿出处: 一像素   

在Javascript中,万物皆对象,但目的也可能有分别,差异常少能够分成两类,即:普通对象(Object)和函数对象(Function)。

貌似来讲,通过new Function发生的靶子是函数对象,其余对象都以平时对象。

比如表明:

function f1(){ //todo } var f2 = function(){ //todo }; var f3 = new
Function(‘x’,’console.log(x)’); var o1 = {}; var o2 = new Object(); var
o3 = new f1(); console.log( typeof f1,//function typeof f2,//function
typeof f3,//function typeof o1,//object typeof o2,//object typeof o3
//object ); >> function function function object object object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function f1(){
    //todo
}
var f2 = function(){
    //todo
};
var f3 = new Function(‘x’,’console.log(x)’);
 
var o1 = {};
var o2 = new Object();
var o3 = new f1();
 
console.log(
    typeof f1,//function
    typeof f2,//function
    typeof f3,//function
    typeof o1,//object
    typeof o2,//object
    typeof o3 //object
);
>> function function function object object object

f1归于函数的证明,最广大的函数定义格局,f2实际是多个无名函数,把这一个无名氏函数赋值给了f2,属于函数表达式,f3不平淡无奇,但也是风姿洒脱种函数对象。

Function是JS自带的靶子,f1,f2在开创的时候,JS会自动通过new
Function(卡塔尔的艺术来塑造那几个指标,由此,那四个对象都以通过new
Function(卡塔尔(英语:State of Qatar)创设的。

在Javascript中创设对象有三种办法:对象字面量和行使new表明式,o1和o2的创立无独有偶对应了那二种艺术,入眼讲一下o3,
如若用Java和C#的思绪来驾驭的话,o3是f1的实例对象,o3和f1是千篇生机勃勃律类型,最少笔者原先这么以为,其实不然…

那么怎么知道啊? 异常粗略,看o3是或不是因而new Function发生的,
显明不是,既然不是函数对象,那正是通常对象 。

通过对函数对象和普通对象的简短明了之后,大家再来通晓一下Javascript中的原型和原型链:

在JS中,每当创造二个函数对象f1
时,该对象中都会放到一些质量,在那之中囊括prototype和__proto__,
 prototype即原型对象,它记录着f1的局地品质和办法。

亟需小心的是,prototype
对f1是不可以看见的,也正是说,f1不会招来prototype中的属性和方法。

function f(){} f.prototype.foo = “abc”; console.log(f.foo); //undefined

1
2
3
function f(){}
f.prototype.foo = "abc";
console.log(f.foo); //undefined

那么,prototype有哪些用呢? 其实prototype的首要意义正是继续。
通俗一点讲,prototype中定义的性质和办法都是预先流出自个儿的“后代”用的,因而,子类完全能够访谈prototype中的属性和措施。

想要知道f1是哪些把prototype留给“后代”,大家要求领悟一下JS中的原型链,那时,JS中的
__proto__
入场了,那男士长的很漂亮妙,隐蔽的也很深,招致于你时数见不鲜不到它,但它在日常对象和函数对象中都留存,
它的成效正是保存父类的prototype对象,JS在经过new
表达式创建八个对象的时候,日常会把父类的prototype赋值给新指标的__proto__属性,那样,就造成了一代代承继…

function f(){} f.prototype.foo = “abc”; var obj = new f();
console.log(obj.foo); //abc

1
2
3
4
function f(){}
f.prototype.foo = "abc";
var obj = new f();
console.log(obj.foo); //abc

现行反革命大家通晓,obj中__proto__保存的是f的prototype,
那么f的prototype中的__proto__中保存的是何许呢? 看下图:

图片 1

如图所示,f.prototype的__proto__中保留的是Object.prototype,Object.prototype对象中也是有__proto__,而从输出结果看,Object.prototype.__proto__
是null,表示obj对象原型链的扫尾。如下图所示:

图片 2

obj对象具备这样三个原型链未来,当obj.foo试行时,obj会先物色自个儿是或不是有该属性,但不会招来自身的prototype,当找不到foo时,obj就本着原型链依次去查找…

在上头的例证中,大家在f的prototype上定义了foo属性,那时obj就能在原型链上找到那一个本性并施行。

 

最终,用几句话总计一下本文中涉及到的最重要:

  1. 原型链的多变真正是靠__proto__
    而非prototype,当JS引擎推行对象的格局时,先找找对象自作者是或不是存在该方法,假若一纸空文,会在原型链上查找,但不会招来本人的prototype。
  2. 叁个对象的__proto__笔录着友好的原型链,决定了自家的数据类型,退换__proto__就等于退换目的的数据类型。
  3. 函数的prototype不归于自己的原型链,它是子类成立的为主,决定了子类的数据类型,是接连子类原型链的大桥。
  4. 在原型对象上定义方法和品质的指标是为了被子类世襲和选用。

 

2 赞 17 收藏 2
评论

图片 3

还并未有收拾,百度时而~

在Javascript中,万物皆对象,但指标也会有分别,差不离能够分成两类,即:普通对象和函数对象。

1、理解Object和Function

Object和Function都以援引类型,是大器晚成种数据布局,封装数据和功效,平常被称为类。

诚如来说,通过new Function发生的靶子是函数对象,别的对象都是普通对象。

Object类型

既然是类,就足以用来创立对象,如 var person = new Object(卡塔尔(قطر‎;

其余,JS中还提供另二个创造对象的形式:对象字面量,如 var persion = {};

上边二种格局的也正是的。

function f1(){ //todo}var f2 = function(){ //todo};var f3 = new Function; var o1 = {};var o2 = new Object; console.log( typeof f1,//function typeof f2,//function typeof f3,//function typeof o1,//object typeof o2,//object typeof o3 //object);>> function function function object object object

Function类型

Function是类,它的对象是怎么样啊?其实便是我们常用的函数。没有错,JS中的函数是指标,是Function类型的实例。如:

function sum(num1,num2){
    return num1+num2
};

除此以外,JS还提供使用函数表明式定义函数的办法,如:

var sum = function(num1,num2){
    return num1+num2;
};
  1. 函数的内部属性:

在函数内部,有七个杰出的指标:arguments和this,arguments是三个类数组对象,包括传入函数中的全部参数。那一个指标还恐怕有有二个誉为callee的习性。该属性是三个指南针,指向具备那几个arguments对象的函数。

ECMAScript5标准化了另一个函数对象的性格:caller,它保存着调用当前函数的函数的引用。

  1. 函数属性和方式:

各样函数都蕴含七个属性:length和prototype;length代表选择参数的个数;prototype保存函数类型的装有实例方法,杰出与类情势,在自定义类型和促成三回九转时要非常注意。

每种函数还带有五个非世襲而来的办法:apply(卡塔尔(قطر‎和call(卡塔尔,它们的界别在于选拔参数的点子各异。那八个章程能扩大函数的功用域,使对象和措施解耦合。

f1归于函数的评释,最广泛的函数定义形式,f2事实上是四个佚名函数,把那么些无名氏函数赋值给了f2,归于函数表明式,f3有时见,但也是生龙活虎种函数对象。

2、驾驭原型对象

要是创制贰个新函数,就能为该函数创造七个prototype属性,该属性指向函数的原型对象。上面通超过实际例代码和图表明。

率先通过布局函数和原型创造实例,代码如下:

function Person(){}

Person.prototype.name = 'xiaoming';

Person.prototype.sayName = function(name){alert(this.name)}

var p1 = new Person();

p1.sayName();// xiaoming

var p2 = new Person();

p2.sayName();// xiaoming

布局函数、原型对象即经过布局函数创制的实例对象时期的关系如下图所示:

图片 4

image

Function是JS自带的对象,f1,f2在创制的时候,JS会自动通过new
Function(卡塔尔(英语:State of Qatar)的点子来营造这么些指标,因而,那四个指标都是透过new
Function(卡塔尔创设的。

3、了然原型链和继承

JS将原型链作为实现持续的首要措施,基本理念是运用原型让四个援引类型世襲另三个援引类型的性质和措施。

原型链达成存豆蔻梢头种基本形式,代码如下:

function Parent(){

this.property = true;

}

Parent.prototype.getParentValue = function(){

return this.property;

}

function Child(){

this.subproperty = false;

}

//子类继承父类

Child.prototype = new Parent();

Child.prototype.getSubValue = function(){

return this.subproperty;

}

var instance = new Child()

console.log(instance.getSubValue);

布局函数、原型对象即经过构造函数创制的实例对象时期的关系如下图所示:

图片 5

image

这种格局达成三番一次有有个最大标题在于蕴含援引类型的原型,那足以经过整合世襲搞定,相当于组成原型链和布局函数,这种办法是JS中最常用的一而再再而三方式。背后的笔触是应用原型链实现对原型属性和章程的接续,而经过借用架构函数的方式达成对实例属性的世襲。

实比方下:

function Parent(){

this.name = name;

this.colors = ['red','blue','green']

}

Parent.prototype.sayName= function(){

return this.name;

}

function Child(){

//继承属性

Parent.call(this,name);

this.age = age;

}

//继承方法

Child.prototype = new Parent();

Child.prototype.constructor = Child;

Child.prototype.sayAge= function(){

return this.age;

}

var instance = new Child('xiaoming','28')

instance.colors.push("black");

consloe.log(instance.colors);// ['red','blue','green','black']

instance.sayName();//xiaoming

instance.sayAge();//28

var instance2 = new Child('xiaoli',30)

consloe.log(instance2.colors);//['red','blue','green']

instance2.sayName();//xiaoli

instance2.sayAge();//30

组成世袭依旧有个小标题,那就是频仍调用超类型布局函数而产生的低成效难题。进而引出达成三番两次最实用的情势–寄生组合式世袭

实比方下:

//借助原型基于已有对象创建对象

function object(o){

function F(){}

F.prototype = o;

return new F();

}

function inheritProtype(Parent,Child){

var prototype = object(Parent.prototype);//创建对象

prototype.constructor = Child;//增强对象

Child.prototype = prototype;//指定对象

}

function Parent(){

this.name = name;

this.colors = ['red','blue','green']

}

Parent.prototype.sayName= function(){

return this.name;

}

function Child(){

//继承属性

Parent.call(this,name);

this.age = age;

}

inheritProtype(Parent,Child);

Child.prototype.sayAge = function(){

return this.age

}

参照他事他说加以考察:JavaScript高端程序设计(第三版)

在Javascript中成立对象有三种艺术:对象字面量和采纳new表明式,o1和o2的始建刚巧对应了那二种方法,重点讲一下o3,
假使用Java和C#的思绪来掌握的话,o3是f1的实例对象,o3和f1是相像档案的次序,最少笔者原先这么感到,其实不然…

那么怎么领会啊? 很简单,看o3是否经过new Function产生的,
显著不是,既然不是函数对象,那正是枯燥没味对象 。

由此对函数对象和日常对象的粗略领悟之后,大家再来领悟一下Javascript中的原型和原型链:

在JS中,每当创立二个函数对象f1
时,该对象中都会停放一些属性,个中囊括prototype和__proto__,
prototype即原型对象,它记录着f1的一些品质和措施。

要求潜心的是,prototype
对f1是不可以预知的,也正是说,f1不会搜索prototype中的属性和章程。

function f(){}f.prototype.foo = "abc";console.log; //undefined

那便是说,prototype有啥用呢? 其实prototype的主要成效正是延续。
通俗一点讲,prototype中定义的品质和措施都以留给本身的“后代”用的,因而,子类完全能够访谈prototype中的属性和方法。

想要知道f1是何许把prototype留给“后代”,大家需求领悟一下JS中的原型链,当时,JS中的
__proto__
进场了,那男子长的很神奇,蒙蔽的也很深,引致于你时一时见不到它,但它在经常对象和函数对象中都设有,
它的效率就是保存父类的prototype对象,JS在通过new
表明式创立七个对象的时候,日常会把父类的prototype赋值给新指标的__proto__本性,这样,就变成了一代代承接…

function f(){}f.prototype.foo = "abc";var obj = new f();console.log; //abc

前日大家通晓,obj中__proto__保存的是f的prototype,
那么f的prototype中的__proto__中保存的是何等吗? 看下图:

如图所示,f.prototype的__proto__中保留的是Object.prototype,Object.prototype对象中也可以有__proto__,而从出口结果看,Object.prototype.__proto__
是null,表示obj对象原型链的竣事。如下图所示:

obj对象具有那样叁个原型链将来,当obj.foo施行时,obj会先物色自个儿是还是不是有该属性,但不会招来自身的prototype,当找不到foo时,obj就本着原型链依次去查找…

在地点的例证中,大家在f的prototype上定义了foo属性,这个时候obj就能在原型链上找到那特性子并实行。

最后,用几句话计算一下本文中关系到的首要性:

原型链的演进真便是靠__proto__
而非prototype,当JS引擎施行对象的办法时,先找找对象自小编是不是留存该办法,假使海市蜃楼,会在原型链上查找,但不会招来自己的prototype。

叁个对象的__proto__记录着团结的原型链,决定了自小编的数据类型,改正__proto__就也正是退换目的的数据类型。
函数的prototype不归属自己的原型链,它是子类成立的主导,决定了子类的数据类型,是三回九转子类原型链的大桥。
在原型对象上定义方法和质量的指标是为着被子类世袭和行使。

上述正是本文的全部内容,希望对我们的上学抱有利于。

发表评论

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

网站地图xml地图