前端基本知识(二):JS的原型链的理解

之前一直对于前端的基本知识不是了解很详细,基本功不扎实,但是前端开发中的基本知识才是以后职业发展的根基,虽然自己总是以一种实践是检验真理的唯一标准,写代码实践项目才是唯一,但是经常遇到知道怎么去解决这个问题,但是不知道使用的是什么一种方法,方法的原理是什么,现在觉得大学里学习的基本知识还是很重要的,一定有自己的理解才能走的更远。

无论以后自己的学习新的技术,但是万变不离其宗,基本扎实,学习效率高。

废话这么多,开始了今天理解的四部分部分。

一、JS的原型链理解方式

二、原型理解

三、规则

四、js常见的创建对象的各种方法

一、原始链理解方式

每一次原型链理解起来很费劲,而且经常容易出错,或者解释的不到位。

1、什么是对象实例,什么是原型(对象)?

2、什么是构造函数?

3、通过原型对象找到构造函数

4、原型的唯一性

5、原型链

6、原型链最终指向为null

7、继承

8、原型链的继承

9、原型链的向上搜索

10、对象的属性可以自定义

11、对象实例不能改动原型属性

12、原型属性的共享

13、原型的动态性

14、原型的重写

我去,这也太多了,不想看了,我已经蒙圈了。等等,学习本身就是一个痛苦的过程,但是当你通过自己的理解的东西,这样运行机制就更容易理解。

你可以这样理解:

1、”人是人生的,妖是妖生的。“人和妖都是对象实例,人他妈和妖他妈都是原型,也叫原型对象。

2、“人出生和妖出生”都是构造一个函数,从无到有的过程

3、“人可以通过人他妈找到人他爸是谁”,也就是通过原型找到构造函数。

4、“人他妈可以生很多小宝宝,但是这些宝宝只有一个妈妈”,这就是原型的唯一性。

5、“人他妈的妈妈,和人他妈的妈妈的妈妈,。。。。”,这就是原型链

6、原型链并不是无限长,通过继承可以不断的往上找,最终原型链指向null

7、“人继承了人他妈的属性,妖继承了妖他妈的属性。”

8、“人继承了人他妈的肤色等等,人他妈继承人他妈他妈的肤色等等。。。”这就是原型继承。

9、“你没有家,你家指的就是你妈家;你妈没有家,那你家指向的就是你妈妈的妈妈的家“,这就是原型链的向上搜索。

10、“你会继承你妈的样子,但是你可以染发剪头发等等”,也就是说对象的属性可以的自定义。

11、"虽然你改变了自己的头发颜色等等,但是你不能改变你妈的样子",这就是对象实例不能改变原型的属性。

12、“你家玩火被你说了话,那就是说你家,你妈家,你弟弟们家,都被少了,这就是原型共享”

13、“你妈外号叫"小翠",邻居都叫你“小翠儿”,但是你妈做了一个帅气的发型,外号改成了“金毛狮王”,邻居都叫你,“金毛狮王子””,这就是原型的动态性。

14、“你妈爱美,整容了,没有人认识,然后又整回去了”,这就是叫原型的整体重写。

 

在用代码说明原型链的之前,我们先弄清楚,函数和function有什么关系,构造函数,原型,实例之间有什么关系?

答:1、所有的函数都是 Function 的实例。

2、在构造函数上都有一个原型属性 prototype,该属性也是一个对象;

3、那么在原型对象上有一个 constructor 属性,该属性指向的就是构造函数;

4、而实例对象上有一个 _proto_ 属性,该属性也指向原型对象,并且该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用。

function person(name){this.name=name}

function mother(){}

mother.prototype={//mother原型自带属性prototype
    age:20,
    home:[‘Beijing‘,‘Shanghai‘]
};

person.prototype=new mother();   //person的原型为mother

var p1=new person(‘Tom‘);     //p1:‘Tom‘;_proto_:20,[‘Beijing‘,‘Shanghai‘]
var p2=new person(‘Mark‘)     //p2:‘Mark‘;_proto_:20,[‘Beijing‘,‘Shanghai‘]
p1.age=24;     //实例不能改变原型的基本属性值,在p1实例下增加一个age的属性,与原型无关
//p1:‘Tom‘,24;_proto_:20,[‘Beijing‘,‘Shanghai‘]

p1.home[0]=‘Shenzhen‘;
//原型中引用类型属相的共享,,正如你烧了你家,就是烧了你全家的家
//p1:‘Tom‘,24;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]
//p2:‘Mark‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]

p1.home=[‘Hangzhou‘,‘Guangzhou‘];
//其实与p1.age=20的操作一样
//p1:‘Tom‘,24,[‘Hangzhou‘,‘Guangzhou‘];_proto_:20,[‘Shenzhen‘,‘Shanghai‘]
//p2:‘Mark‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]

delete p1.age;
//删除自定义的属性之后,原本覆盖的原型就可以重见天日,这就是搜索机制
//p1:‘Tom‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:20,[‘Shenzhen‘,‘Shanghai‘]
//p2:‘Mark‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]

person.prototype.lastname=‘Cheng‘;
//改写原型,动态反应在实例中。我们改写的是person的原型,往mother里加一个last那么属性
//等同于mother.lastname=‘Cheng‘
//这里并不是mother。prototype,改动不同的层次,效果会有很大的差异
//p1:‘Tom‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:‘Cheng‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]
//p2:‘Mark‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:‘Cheng‘;_proto_:20,[‘Shenzhen‘,‘Shanghai]

person.prototype={
    age:28,
    address:{country:‘USA‘,city:‘Washington‘}
};
var p3=new person(‘obama‘);
//重写原型,这个时候person的原型完全改变
//p1:‘Tom‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:‘Cheng‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]
//p2:‘Mark‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:‘Cheng‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘]
//p3:‘obma‘;_proto_:28{country:‘USA‘,city:‘Washington‘}

mother.prototype.no=20110408;
//改写原型的原型,动态反应在实例中,
//p1和p2会改变,但是p3不会改变,p3与mother无关
//p1:‘Tom‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:‘Cheng‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘],20110408
//p2:‘Mark‘,[‘Hangzhou‘,‘Guangzhou‘];_proto_:‘Cheng‘;_proto_:20,[‘Shenzhen‘,‘Shanghai‘],20110408
//p3:‘obama‘;_proto_:28{country:‘USA‘,city:‘Washington‘}

mother.prototype={
    car:2,
    hobby:[‘run‘,‘walk‘]
};
var p4=new person(‘Tony‘);
//重写原型的原型,这时候mother的原型已经发生完全的变化
//上面的person和mother已经断开联系了,mother怎么变都不会影响person
//p4:‘Tony‘;_proto_:28{country:‘USA‘,city:‘Washington‘}

person.prototype=new mother();   //再次绑定
var p5=new person(‘Luccy‘);
//这个时候如果需要应用这边改动的话,需要重新将person原型绑定在mother上
//p5:‘Luccy‘;_proto_:2,[‘run‘,‘walk‘]

p1.__proto__.__proto__.__proto__.__proto__    //null,原始链终点是null
mother.__proto__.__proto__.__proto__     //null ,原型链的终点事null

二、原型理解

javascript中,原型也是一个对象,通过原型可以实现对象的属性继承,javascript的对象中都包含了一个protype内部属性,这个属性对应的就是该对象的原型。javascript的原型对象中还包含一个constructor属性,这个属性对应创建所有指向该原型的实例的构造函数。

注意:protype作为对象的内部属性是不可以直接访问的,但是谷歌浏览器提供了一个_proto_这个非标准的访问器。

三、规则

javascript中,每一个函数都有一个prototype属性,当一个函数被用作构造函数来创建实例,这个prototype属性值会被作为原型赋值给所有的对象实例(也就是所有实例设置“_proto_”属性)。

对象:prototype属性

原型对象:protype属性,construction属性

对象实例:_proto_属性

new的过程分为三步:

var p=new person(‘张三‘,20);

1、var p={};初始化一个对象p

2、p._proto_=person.prototype;将对象p的_proto_属性设置为person.prototype

3、person.call(‘张三‘,20);调用构造函数person来初始化p。

原型链继承的主要问题在于属性的共享。原型继承的改良方法:

(1)组合继承

function mother(age){
    this.age=age;
    this.hobby=[‘running‘,‘football‘]
}
mother.prototype.showAge=function(){
    console.log(this.age);
}

function person(name,age){
    mother.call(this,age);   //第二次执行
    this.name=name;
}
person.prototype=new mother();   //第一次执行
person.protype.constructor=person;
person.prototype.showName=function(){
    console.log(this.name);
}
var p1=new person(‘jack‘,20);
p1.hobby.push(‘basketball‘);     //p1:‘jack‘;_proto_:20,[‘running‘,‘football‘]
var p2=new person(‘mark‘,18);    //p2:‘mark‘;_proto_:18,[‘running‘,‘football‘]

执行结果如图所示:

四、js常见的创建对象的各种方法

(1)原始模式

//1、原始模式。对象字面量方式
var person={
name:‘Jack‘,
age:18,
sayName:function(){alert(this.name);}
};
//1、原始模式,object构造函数方式
var person=new object();
person.name=‘Jack‘;
person.age=18;
person.sayName=function(){alert(this.name);};

代码重用量大,所以产生了工厂模式。

(2)工厂模式

//2、工厂模式,定义一个函数创建对象
function createPerson(name,age){
var temp=new Object();
person.name=name;
person.age=age;
person.sayName=function(){alert(this.name);};
return temp;
}

工厂模式就是批量成产,效率

(3)构造函数

//3、构造函数模式,为对象顶一个构造函数
function person(name,age){
this.name=name;
this.age=age;
this.sayName=function(){alert(this.name);};
}
var p1=new person(‘Jack‘,18);   //创建一个p1对象
person(‘Jack‘,18);    //属性方法都给window对象,window.name=‘Jack‘

构造函数与c++,、java构造函数类似,易于理解。

(4)原型方式

//4、原型模式,直接定义prottype
function person(){
person.prototype.name=‘Jack‘;
person.prototype.age=18;
person.prototype.sayName=function(){alert(this.name);}
}

//4、原型模式,字面量定义的方式
function person(){
person.prototype={
name:‘Jack‘,
age:18,
sayName:function(){alert(this.name);}
};
var p1=new person();  //name=‘Jack‘
var p2=new person();  //name=‘Jack‘
}

这里需要注意的是原型属性和方法的共享,即所有实例中都只是引用原型中的属性方法,任何一个地方差生的改动都会引起其他实例的变化。

时间: 2024-10-08 10:03:41

前端基本知识(二):JS的原型链的理解的相关文章

前端基本知识:JS的原始链的理解

一.JS的原型链理解方式 二.原型理解 三.规则 四.js常见的创建对象的各种方法 一.原始链理解方式 每一次原型链理解起来很费劲,而且经常容易出错,或者解释的不到位. 1.什么是对象实例,什么是原型(对象)? 2.什么是构造函数? 3.通过原型对象找到构造函数 4.原型的唯一性 5.原型链 6.原型链最终指向为null 7.继承 8.原型链的继承 9.原型链的向上搜索 10.对象的属性可以自定义 11.对象实例不能改动原型属性 12.原型属性的共享 13.原型的动态性 14.原型的重写 我去,

js之原型链的理解

在js中,原型也是一个普通的对象,通过原型我们能够实现对象的属性继承. 首先,我们要明确引用类型有Array.Object.Function,这些引用类型都是能够自由的扩展属性. 1 var obj = {}; 2 obj.a = 10; 3 obj.b = 20; 4 5 obj; // Object {a: 10, b: 20} 我们上面说的这几个引用类型都有一个属性__proto__,这是一个普通的对象.而这个__proto__属性是指向它的构造函数的prototype属性.我们可以在代码

关于js中原型链的理解

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,一个对象.无论什么时候,我们只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性对象指向函数的原型对象.在默认情况下,所有原型对象都会自动获得一个 constroctor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针.例如: function Person(){} 当我们创建这个Person函数(对象)的时候,该函数便有了一个prototype属性,它的

JS中原型链的理解

在谈原型链之前,我们首先要了解自定义函数与 Function 之间是什么关系,而构造函数.原型和实例之间又存在什么千丝万缕的关系呢?其实,所有的函数都是 Function 的实例.在构造函数上都有一个原型属性 prototype,该属性也是一个对象:那么在原型对象上有一个 constructor 属性,该属性指向的就是构造函数:而实例对象上有一个 _proto_  属性,该属性也指向原型对象,并且该属性不是标准属性,不可以用在编程中,该属性用于浏览器内部使用. 1 // _proto_ 2 在函

JS中原型链深刻理解

1.自定义的构造函数定义对象 2.定义函数

怎么理解js的原型链继承?

前言 了解java等面向对象语言的童鞋应该知道.面向对象的三大特性就是:封装,继承,多态. 今天,我们就来聊一聊继承.但是,注意,我们现在说的是js的继承. 在js的es6语法出来之前,我们想实现js的继承关系,需要借助于原型链.之前的文章,我有讲过原型和原型链的概念.在这,再重新回顾一下. js中万物皆对象,每个对象都有一个隐式原型 __proto__ ,指向创建它的构造函数的原型对象. 函数(构造函数)除了有一个隐式原型对象,还有一个属性prototype,它指向一个对象,这个对象就是原型对

对原型链的理解 语言表达能力不好 直接用代码,哈

分享一下 我对原型和原型链的理解 原型对象: function People(nameValue,ageValue,fondValue)            {                this.name = nameValue;                this.age = ageValue;                this.fond = fondValue;            } People.prototype.rule = function()         

原型链的理解

### 原型链的理解 #### 概念 + javascript每一个对象**包括原型对象**都有一个内置的`proto`属性指向创建他的函数对象的原型对象,即`prototype`属性 #### 作用 + 实现对象的继承 ### 理解 1.函数对象 + 在javascript中,函数就是对象 2.原型对象 + 当定义一个函数对象的时候,会包含一个预定的属性,`prototype`,这就属性称之为原型对象 3.\__proto__ + javascript 在创建对象的时候,都会有一个\_prot

面向对象(2 )构造函数 原型 原型链的理解

面向对象(2) 原型 原型链的理解 1.面向对象的目的就是生成对象object. 2.生成对象的方式 (1)单例模式(字面量定义)var obj={} (2)类的实例 var obj=new Object() (3)工厂模式 (4)构造函数 工厂模式和构造函数的区别? 工厂模式,生成的对象必须要返回,构造函数模式不用return,构造函数模式默认return旳是this,在构造函数内的this就是实例对象. 构造函数如果人为return的不是对象,直接忽略,如果人为return的是对象,就取代t