深入浅出javascript对象原型

1原型继承vs类继承

(1)类继承

java 中:指在已有的一个类基础上创建新类的过程。–复制行为

(2)原型继承

指在一个对象的基础上创建新对象的过程。原型指在这过程中作为基础的对象。
–委托行为,关联行为。并不是把基础对象的属性copy 到自身

2 prototype

对象(函数)的内置属性,也有少数值为空,指向另外一个对象,即是另外对象的引用

3 (重点)prototype 和 proto 的区别

这个话题首先要先搞清楚 对象函数 ,2个在这方面的表现是不一样的。

函数就是对象的一个子类型(从技术角度来说就是“可调用的对象”)。有时我们说对象是包含函数,但是有时是不包含的,这点要注意。

(1)任何对象都拥有 proto(隐式原型) 属性, 一般指向他们的构造函数的原型 (prototype) ,对象的prototype 是内置的,不可直接访问 ,a.prototype 是undefined

__proto__ 绝大多数(不是所有!)浏览器也支持一种非标准的方法来访问内部[[Prototype]]属性:
function foo(){

}
console.log(Object.getPrototypeOf( a )===foo.prototype);
console.log(a.__proto__==foo.prototype);

(2)所有函数都拥有prototype (显式原型)属性,函数是可以直接访问的

foo.prototype 。当然 foo.__proto__ 也是ok 的。

(5)

3 原型领域的一些重要姿势

(1)所有函数都是Function 的 实例,Function 本身也是函数,函数和对象有时是可以一起说成对象的,例如都可以从函数创建而来的。

(2)Function,Object,Array 这些引用是函数来的。有时我们也会成为对象。

(3)原型链的顶端是Object.prototype,其 proto为 null

(4)constructor

定义一个函数时 会让他的原型指向函数本身

console.log( Function.prototype.constructor === Function); // true
console.log(Object.prototype.constructor === Object);     // true
var a=new Object();
console.log(a.constructor === Object);     // true    表面有点向java 一样 从Object 创建而来,其实是根据原型链找到的
console.log(Array.prototype.constructor === Array);       // true

(5)原型继承常规机制

![image](https://github.com/5201314999/5201314999.github.io/tree/master/uploads/jizhi.png)  

(6)es5,es6 设置函数关联

1
2
3
4
5
6
7
8
9
10
11
// ES6之前需要抛弃默认的Bar.prototype
Bar.ptototype = Object.create( Foo.prototype );
// ES6开始可以直接修改现有的Bar.prototype
Object.setPrototypeOf( Bar.prototype, Foo.prototype);
// 摒弃的2种
bar.prototype = foo.prototype 这种关联会改变foo.prototype ,直接引用
bar.prototype = new foo();
这样的确会创建一个关联到 foo.prototype 的新对象。 但是它同时 也执行了对 foo 函数的调用,如果 foo 函数中有给this添加属性、修改状态、写日志等,就会影响到 bar() 的 “后代” 。

4 原型链的概念

如果想要找到一个对象的属性,首先会先在自身查找,如果没有,就会通过proto属性一层层的向上查找,直到原型链的顶端 Object.prototype(proto: null)
这种通过某种纽带(proto)将对象之间形成一种继承关系 这种关系呈现出一种链条的形状 将这种链条称之为原型链

5创建对象的方法

(1)字面量

var a={
    name:1
};

(2)构造函数

function Person(){
    this.a=1;   
}
var a=new Person(b);

(3)Object.create 函数

var b={
    name:1
};
var a=Object.create(b);

6 几种原型图,都是建立在prototype 和 proto 的基础上的。

(1)字面量对象
    ![image](https://github.com/5201314999/5201314999.github.io/tree/master/uploads/const.png)
(2)函数
    ![image](https://github.com/5201314999/5201314999.github.io/tree/master/uploads/function.png)
(3)数组
     ![image](https://github.com/5201314999/5201314999.github.io/tree/master/uploads/array.png)
(4)对象
    ![image](https://github.com/5201314999/5201314999.github.io/tree/master/uploads/obj.png)

7 arr.push() 是怎么来的 ,其实是在 Array.protyotype.push 这样来的。

8 检测关联

(1)a instanceof Foo; // true 左侧是对象,右侧是函数


(2)b.isPrototypeOf(a) //检测2 个对象的 


(3)Object.getPrototypeOf( a )  利用函数和对象2种情况各自的原型特点去判断是否有关联

9 原型有时会屏蔽设置值的。用得不多要用的话再查询 书籍,脑力有限,挑重点的即可。

备注:本篇文章参考了《你不知道的javascript 上》 ,李佳怡的知乎,简书上的文章。