原型链的理解

### 原型链的理解

#### 概念

+ javascript每一个对象**包括原型对象**都有一个内置的`proto`属性指向创建他的函数对象的原型对象,即`prototype`属性

#### 作用

+ 实现对象的继承

### 理解

1.函数对象

+ 在javascript中,函数就是对象

2.原型对象

+ 当定义一个函数对象的时候,会包含一个预定的属性,`prototype`,这就属性称之为原型对象

3.\__proto__

+ javascript 在创建对象的时候,都会有一个\_proto\_的内置属性,用于指向创建它的函数对象的`prototype`。原型对象也有\_proto\_ 属性。因此在不断的指向中,形成了原型链。

4.new

+ 当使用new关键字去调用构造函数就相当于执行啦

5.constructor

+ 原型对象prototype上都有个预定义的constructor属性,用来引用它的函数对象。这是一种循环引用

?

### 继承

+ **构造函数绑定**

> 使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:

```javascript
function test(name,height) {
this.name = name
this.height= height
};
function trys(age){
this.age = age
test.apply(this,["张三","180cm"])
//apply(this,argument)第一个参数为改变this指向,第二个参数为一个伪数组每一项对应 调用apply的函数的形参。
//call(this,name,height) 第一个参数为this,后面参数为调用call的函数的形参。
}
let person = new trys;
person.age = "18"
console.log(person)
```

+ prototype模式

```javascript
function test(name,height) {
this.name = name
this.height= height
this.do=function(hobby){
console.log("我是"+this.name+"我今年"+this.age+"岁"+"身高"+this.height+"我喜欢"+hobby)
}
};
function trys(age){
this.age = age
}
trys.prototype =new test
trys.prototype.constructor = trys;
// trys.prototype =new test 将trys的constructor 属性指向了test,每一个实例对象也会有一个constructor属性默认指向prototype的constructor 属性,person.constructor==test
所以需要将trys的constructor属性重新指回trys
let person = new trys;
person.name = "张三"
person.age = 18
person.height = 180
person.do("打羽毛球")
console.log(person)
```
![](http://p0zfk1qh0.bkt.clouddn.com/markdown001.png)

+ 直接继承prototype
> 是对第二种方法的改进。由于person对象中,不变的属性都可以直接写入person.prototype。所以,我们也可以让man()跳过 person(),直接继承person.prototype。

```javascript
function person (){
}
person.prototype.skill = "开车"
function man(){
this.hobby = "泡妞"
}
man.prototype = person.prototype;
man.prototype.constructor = man;
let xiaoming = new man ;
console.log(xiaoming.skill);
```
+ 利用空对象作为中介

> 用第三种方法会改变person的constructor 的指向 所以有了这种方法 定义一个空的
> 对象作为中介

```javascript
function person (){
}
person.prototype.skill = "开车"
function man(){
this.hobby = "泡妞"
}
function F (){
}
F.prototype =person.prototype
man.prototype = new F()
man.prototype.constructor = man;
let xiaoming = new man ;
```
> 我们将上面的继承封装

```javascript
  function extend(Child, Parent) {
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
  }
```
+ 拷贝继承

>把父对象的所有属性和方法,拷贝进子对象

``` javascript
function extend2(Child, Parent) {
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
      c[i] = p[i];
      }
    c.uber = p;
  }
```

+ 非构造函数继承
```javascript
let person = {
skill:"行走"
}
let xiaomming = {
age:"18"
}
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
  }
let xiaoming = object(person)
console.log(xiaoming.skill) //行走
```
+ 浅拷贝

***这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。***

```javascript
let person = {
skill:"行走"
}
let xiaomming = {
age:"18"
}
function extendCopy(p) {
    var c = {};
    for (var i in p) {
      c[i] = p[i]; //遍历p对象,将p对象的每一个属性 都赋值给c对象的每一项
    }
    return c;
  }
let xiaoming = extendCopy(person);
console.log(xiaoming.skill)//行走
```
+ 深拷贝

>"深拷贝",就是能够实现真正意义上的数组和对象的拷贝。只要递归调用"浅拷贝"就行了。
``` javascript
let person = {
skill:"行走"
}
let xiaomming = {
age:"18"
}
  function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === ‘object‘) {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }
var xiaoming = deepCopy(person)
console.log(xiaoming.skill)
```

时间: 2024-11-05 21:39:07

原型链的理解的相关文章

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

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

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

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

JS原型链的理解

<JavaScript高级程序设计>是一本好书,下面总结一下书中关于原型链的讲解. 本文从对象的创建开始,逐渐引出原型链的背景.作用以及ECMA对原型链的定义1.理解对象两种常用的创建对象的方法之一是new一个Object对象,并为它添加属性和事件var person = new Object();person.name = "wzk";person.age = 24;person.sayName = function(){ alert(this.name);}; 另一种是

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

之前一直对于前端的基本知识不是了解很详细,基本功不扎实,但是前端开发中的基本知识才是以后职业发展的根基,虽然自己总是以一种实践是检验真理的唯一标准,写代码实践项目才是唯一,但是经常遇到知道怎么去解决这个问题,但是不知道使用的是什么一种方法,方法的原理是什么,现在觉得大学里学习的基本知识还是很重要的,一定有自己的理解才能走的更远. 无论以后自己的学习新的技术,但是万变不离其宗,基本扎实,学习效率高. 废话这么多,开始了今天理解的四部分部分. 一.JS的原型链理解方式 二.原型理解 三.规则 四.j

Javascript-我对作用链、闭包、原型及原型链的理解

Javascript-基础概念总结(2) 最近学习一些javascript基础知识,也解决了很多之前的疑惑,记得第一次被问及怎样理解闭包时,我的回答是:就是类似于封装吧!现在想想是有多白痴,学习技术是需要逻辑性很强的,技术注重用事实和数据说话,每一点都需要理解透彻,在技术上没有猜测,没有套路,以后自己在回答技术性的问题时,应做到知道就是知道,不理解或不太明白的,就诚实对待,这样有助于自己积累知识,了解自己的不足,从而提升自己.讲了那么多题外话,是为了让自己认识到应真诚的对待学习.下面是一些我的知

JS原型、原型链深入理解

原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性. 一.初识原型在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个”[[Prototype]]”内部属性,这个属性所对应的就是该对象的原型.“[[Prototype]]”作为对象的内部属性,是不能被直接访问的.所以为了方便查看一个对象的原型,Fir

JS中原型链的理解

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

JavaScript原型链的理解

一.原型链的概念 JavaScript是一门面向对象的编程语言,JavaScript 中的所有事物都是对象,并且对象与对象之间不是彼此独立的,而是有"继承"关系的. 这种"继承"关系与Java或者C#中的继承不同.Java或C#中是有类的概念的,子类继承父类,通过extends关键字实现:而JavaScript中没有真正意义上的class(类),但有与之类似的概念--原型对象:A继承B,则A的"__proto__"属性会指向B的"pro

关于javascript中原型和原型链的理解

对于js中的原型以及原型链,笔者一直觉得有些迷惑,对于其中的概念是大致理解的,但是如果让笔者说出来就感觉比较难以清晰的表达出来,所以就在这里做一下总结,有疑问的时候再翻出来回顾一下 首先,我们看一段代码 function Person() { } var person = new Person(); console.log(person); console.log(Person); console.log(Object) console.log(person.prototype); consol