美文网首页让前端飞JavaScript 进阶营前端开发笔记
关于javascript的原型和原型链,看我就够了(一)

关于javascript的原型和原型链,看我就够了(一)

作者: 陌上寒 | 来源:发表于2018-11-03 00:46 被阅读10次

    关于js的原型和原型链,有人觉得这是很头疼的一块知识点,其实不然,它很基础,不信,往下看
    要了解原型和原型链,我们得先从对象说起

    创建对象

    创建对象的三种方式:

    对象直接量

    通过对象直接量创建对象,这是最简单也是最常用的创建对象的方式

    var empty = {};
    var pos = {x:12,y:23};
    var pos2 = {x:pos.x,y:pos.y+1};
    var author={
        "my name":"陌上寒",//属性名带空格,必须用引号包裹
        'article-title':"关于javascript的原型和原型链,看我就够了(一)",//属性名带连字符,必须用引号包裹
        "if":"使用保留字作为属性名,必须用引号包裹"//使用保留字作为属性名,必须用引号包裹
    }
    

    通过new创建对象

    通过new运算符创建并初始化一个新对象,关键字new后跟随一个函数调用,这个函数成为构造函数(constructor),构造函数用来初始化一个新对象,js包含了一些内置的构造函数

    var  obj = new Object()//创建一个空对象等同于 var obj = {}
    var  arr = new Array()//创建一个空数组等同于 var arr = []
    ...
    

    上面的Object(),Array(),都是js内置的构造函数
    除了内置的构造函数,我们还可以使用自定义构造函数来初始化对象

    function fun(){
        console.log("这是一个自定义构造函数")
    };
    var myObj= new fun();
    

    Object.create()

    这个创建对象的方法似乎有些陌生,它创建一个新对象,包含两个参数,

    第一个,必需。 要用作原型的对象。 可以为 null
    第二个,可选。 包含一个或多个属性描述符的 JavaScript 对象

    const obj = Object.create({x:1})//obj 继承了属性x
    
    const obj2 = Object.create(Object.prototype, {
          foo: {
            writable: true,
            configurable: true,
            value: "hello"
          }
        })
        console.log(obj2);//输出{foo: "hello"}
    const obj3 = Object.create(null)//obj3不继承任何属性和方法
    

    创建一个空对象

    //以下三种方法等效
    var obj1 = {};
    var obj2 = new Object()
    var obj3 = Object.create(Object.prototype)
    

    今天重点说原型,明天我们再把Object.create()展开讲述
    简单回顾以下,以上就是创建对象的三种方式

    • 通过对象直接量
    • 通过new创建对象
    • 通过Object.create()
      马上进入正题了,还差一点点

    对象分类

    我们都知道 JavaScript中万物皆对象,但对象之间也是有区别的。分为函数对象普通对象
    函数对象可以创建普通对象,(这个我们上面讲过了),回顾一下

    function fun(){
        console.log("这是一个自定义构造函数")
    };
    var myObj= new fun();
    

    普通对象没法创建函数对象,凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断。

    function f1(){};
    typeof f1 //"function"
    
    var o1 = new f1();
    typeof o1 //"object"
    
    var o2 = {};
    typeof o2 //"object"
    

    关于函数的创建,注意以下写法等价

    function f1(){}
    等价于
    var f1 = new Function();
    
    function f21(a,b){
      alert(a+b);
    }
    f21(1,2)
    等价于
    var f22 = new Function('a','b',"alert(a+b)");
    f22(1,2)
    

    简单回顾一下
    我们将对象分为函数对象普通对象,函数对象的级别要要高于普通对象,可以通过函数对象创建普通对象,但是无法通过普通对象创建函数对象
    好了,进入正题!

    何为js原型

    每一个js对象(null除外)都和另一个对象相关联,“另一个”对象就是原型,每一个对象都从原型继承属性
    所有通过对象直接量创建的对象都具有同一个原型对象,可以通过Object.prototype获取对原型对象的引用,注意以下代码

    //dmeo1
    const obj =new Object()
    //等价于 const obj ={}
    //等价于const obj = Object.create()
    alert(obj.prototype)//undefined
    alert(Object.prototype)//[object Object]
    //demo2
    function fun(){
        console.log("这是一个自定义构造函数")
    };
    alert(fun.prototype)//[object Object]
    

    看以上代码,obj 为普通对象,obj的prototype为undefined,Object为js内置构造函数,Object存在prototype
    我们得出以下结论
    每一个函数对象都有一个prototype属性,但是普通对象是没有的;
    换个方式再说一遍,只有函数对象才会存在prototype属性,普通的对象不存在
    还没结束,看如下代码

    function fun(){
        console.log("这是一个自定义构造函数")
    };
    console.log(fun.prototype)
    

    输出:

    image
    const obj = {}
    console.log(obj.__proto__);
    

    输出

    image
    const str='陌上寒'
    console.log(num.__proto__);
    

    输出

    image

    constructor

    是构造函数创建的实例的属性,该属性的作用是指向创建当前对象的构造函数。(这个不是我们今天重点要介绍的)

    _proto_

    这是什么?根据我们的console.log,不难发现,函数对象,普通对象,都存在proto,这是什么呢?proto和原型链有什么联系呢?proto指向谁呢?

    我们明天继续探讨js原型和原型链,不见不散
    原文链接
    参考链接
    简单理解js的prototype属性
    基于js中的原型(全面讲解)
    JS原型与原型链的深入理解
    三张图搞懂JavaScript的原型对象与原型链

    陌上寒个人博客

    相关文章

      网友评论

        本文标题:关于javascript的原型和原型链,看我就够了(一)

        本文链接:https://www.haomeiwen.com/subject/xgbhxqtx.html