原型链

原型链

创建对象有几种方法

3种方法

字面量对象

var o1 = {name:'o1'};
var o11 = new Object({name: 'o11'});

显式构造函数

var M = function(){
        this.name = 'o2'}
var o2 = new M();

Object.create()方法

使用原型链连接,与前两种方法不太一样

var P = {name:'o3'};
var o3 = Object.create(P);

原型 构造函数 对象实例 原型链

原型链的原理

原型链关系

从一个实例对象往上找构造这个实例的相关联的对象,这个相关联的对象往上找又有创造他的上一级的原型对象,以此类推,一直到object.prototype终止

原型链是js实现类与继承的基石

原型链和类与继承的关系

原型对象 构造函数 实例的关系

  1. 只有函数才有prototype, 对象没有(函数也是对象)

  2. 只有实例对象有__proto__,函数也有__proto__,因为函数也是对象xx.__proto__ = Function.prototype

  3. 修改了实例也就修改了实例上一级的原型对象

instanceof的原理

instanceof原理

判断函数属性是否是实例原型对象(constructor更严谨)

new运算符

1.一个新对象被创建。它继承自foo.prototype

2.构造函数foo被执行。执行的时候,相应的传参会被传入,同时上下文(this会被指定为这个新实例。new foo等同于 new foo(),只能用在不传递任何参数的情况下。

3.如果构造函数返回一个对象,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象

源码

proto.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>原型链</title>
</head>
<body>
    <script type="text/javascript">
        //第一种方式:字面量
        var o1 = {name: 'o1'};//o1 {name: "o1"}
        var o2 = new Object({name: 'o2'});//o2 {name: "o2"}

        //第二种方式:构造函数
        var M = function(name){
            this.name=name;
        };
        var o3 = new M('o3');//o3 M{name: "o3"}

        //第三种方式:Object.create 原型链连接
        var P = {name: 'p'};
        var o4 = Object.create(P);//o4 {}   o4.name "p"


        //原型链原理
        M.prototype.say = function(){
            console.log('say hi');
        }
        var o5 = new M('o5');


        //实现new运算符的效果 即工作原理
        var new2 = function(func) {
            var o = Object.create(func.prototype);//创建空对象,关联构造函数的原型对象
            var k = func.call(o);//执行构造函数
            if (typeof k === 'object')//判断构造函数的运行结果是否为对象类型
            {
                 return k
            }else{
                return o
            }
        }
    </script>

</body>
</html>