博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
原型链的理解
阅读量:6573 次
发布时间:2019-06-24

本文共 3641 字,大约阅读时间需要 12 分钟。

### 原型链的理解

#### 概念

+ 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)
```

转载于:https://www.cnblogs.com/keyubin/p/8044903.html

你可能感兴趣的文章
notepad++列编辑操作
查看>>
2015年2月3日
查看>>
LI 导航
查看>>
交流:Ghost版系统安装简单分析
查看>>
简单的jquery代码实现图片轮播
查看>>
IDEA的常用配置一键导入及优化内存
查看>>
keytool 错误 java.io.IOException: incorrect AVA format
查看>>
$.ajax()方法详解(转)
查看>>
java 冒泡排序
查看>>
【CSS】Table样式
查看>>
Qt Quick编程(1)——QML的核心部分ECMAScript
查看>>
js 替换非法字符
查看>>
(转)C# Winform应用程序占用内存较大解决方法整理
查看>>
win10下安装mysql5.6 zip形式步骤
查看>>
Shell:while语句、for语句、if语句
查看>>
HTTP缓存原理及相关知识(2)-CDN
查看>>
eclipse代码编辑区字符串自动转义设置
查看>>
思考XSS攻击和跨站伪造请求CSRF
查看>>
实验四恶意代码分析技术 201421430029
查看>>
神一样的代码:
查看>>