最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 原型继承

    正文概述 掘金(用户6380570519320)   2020-12-31   473

    [[Prototype]]

    JavaScript 中,所有的对象都有一个隐藏的 [[Prototype]] 属性,它要么是另一个对象,要么就是 null

    proto

    • 通过 [[Prototype]] 引用的对象被称为“原型”,用 obj.__proto__ 访问它
       let animal = {
         eats: true
       };
       let rabbit = {
         jumps: true
       };
      
       rabbit.__proto__ = animal; // 设置 rabbit.[[Prototype]] = animal
       // rabbit 能使用 animal 的所有属性和方法
         
       console.log(rabbit.eats) // true
      
      • __proto__ 的值可以是对象,也可以是 null。而其他的类型都会被忽略
      • __proto__ 与内部的 [[Prototype]] 不一样。__proto__[[Prototype]] 的 getter/setter。
      • __proto__ 属性有点过时了,用函数 Object.getPrototypeOf/Object.setPrototypeOf 来取代 __proto__ 去 get/set 原型

    “this” 的值

    无论在哪里找到方法:在一个对象还是在原型中。在一个方法调用中,this 始终是点符号 . 前面的对象。

        // animal 有一些方法
      let animal = {
        walk() {
          if (!this.isSleeping) {
            alert(`I walk`);
          }
        },
        sleep() {
          this.isSleeping = true;
        }
      };
    
      let rabbit = {
        name: "White Rabbit",
        __proto__: animal
      };
    
      // 修改 rabbit.isSleeping
      rabbit.sleep();
    
      alert(rabbit.isSleeping); // true
      alert(animal.isSleeping); // undefined(原型中没有此属性)
    

    for…in 循环

    • for..in 循环会迭代继承的属性,即会获得原型的属性
    • Object.keys 只返回自己的 key
    • obj.hasOwnProperty(key):如果 obj 具有自己的(非继承的)名为 key 的属性,则返回 true
    • 思考 任务

    F.prototype

    F.prototype 属性仅在 new F 被调用时使用,它为新对象的 [[Prototype]] 赋值

    function F() {}
    let f = new F
    f.__proto__ == F.prototype // true
    
    • 每个实例对象都会保持对旧的 prototype 的引用
    • 每个函数都有 prototype 属性,默认的 "prototype" 是一个只有属性 constructor 的对象,属性 constructor 指向函数自身。
      F.prototype.constructor == F // true
      
    • 通过实例对象的 constructor 来创建一个和它类似的对象
      let ff= new f.constructor() // ff 为 F 的实例对象
      
    • prototype 增加属性
      F.prototype.name = "ddd" // {name: "ddd", constructor: ƒ}
      
      • 任务思考链接

    原生的原型

    Object.prototype

    let obj = {}
    obj.__proto__  === Object.prototype // true
    
    • let obj = {} 创建了一个对象,其相当于 new Object(),因此 obj[[Protopype]] 会指向 Object.prototype

    其他内建原型

    内建对象,像 Array、Date、Function 及其他,都在 prototype 上挂载了方法。所有的内建原型顶端都是 Object.prototype 。(更直观的图示)

    • null:Object.prototype.__proto__ === null
      let arr = [1, 2, 3];
      
      // 它继承自 Array.prototype?
      alert( arr.__proto__ === Array.prototype ); // true
      
      // 接下来继承自 Object.prototype?
      alert( arr.__proto__.__proto__ === Object.prototype ); // true
      
      // 原型链的顶端为 null。
      alert( arr.__proto__.__proto__.__proto__ ); // null
      

    基本数据类型

    • 字符串、数字和布尔值上会被包装成对象,然后调用 String.prototypeNumber.prototypeBoolean.prototype 中的方法。
    • nullundefined 没有对象包装器

    更改原生原型

    String.prototype.show = function() {
       alert(this);
    }
    
    "BOOM!".show(); // BOOM!
    
    • 原型是全局的,所以很容易造成冲突

    原型方法,没有 _proto_ 的对象

    proto 被认为是过时且不推荐使用的,可以用新方法代替。现代的方法有:

    • Object.create(proto, [descriptors]) —— 利用给定的 proto 作为 [[Prototype]] 和可选的属性描述来创建一个空对象。
    • Object.getPrototypeOf(obj) —— 返回对象 obj 的 [[Prototype]]
    • Object.setPrototypeOf(obj, proto) —— 将对象 obj 的 [[Prototype]] 设置为 proto。
      let animal = {
        eats: true
      };
      
      // 创建一个以 animal 为原型的新对象
      let rabbit = Object.create(animal, {
        jumps: {
          value: true
        }
      });
      
        alert(rabbit.eats); // true
      
        alert(Object.getPrototypeOf(rabbit) === animal); // true
      
        Object.setPrototypeOf(rabbit, {}); // 将 rabbit 的原型修改为 {}
      
    • 比复制 for..in 循环中的属性更强大的对象克隆方式:
      let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
      // 此调用可以对 obj 进行真正准确地拷贝,包括所有的属性
      

    "Very plain" objects

    • obj.__proto__ = 11 该表达式能否正确运行??(详情)__proto__obj 的原型即 Object.prototype 的访问器属性,因此每次赋值的时候只会调用原型中对应方法。
    • 如何使 __proto__ 成为对象的属性?
      let o = Object.create(null) 
      // 原型为 null,没有继承的 __proto_ 访问器属性
      o.__proto__ = 111 // right
      

    起源地下载网 » 原型继承

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元