zoukankan      html  css  js  c++  java
  • 原型笔记

    • 1. Object.getOwnPropertyNames()

      在学习使用该方法的时候,查阅了《JavaScript高级程序设计》与 MDN 来综合学习。

      先来看看MDN对其的表述:

      参数

         obj:
      一个对象,其自身的可枚举和不可枚举属性的名称被返回。

      返回值

          在给定对象上找到的属性对应的字符串数组。

       描述

        Object.getOwnPropertyNames() 返回一个数组,该数组对元素是 obj自身拥有的枚举或不可枚举属性名称字符串。 数组中枚举属性的顺序与通过 for...in 循环(或 Object.keys)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。

      

      同时,举出了几个例子来表显示,例如:

    var arr = ["a", "b", "c"];
    console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
    
    // 类数组对象
    var obj = { 0: "a", 1: "b", 2: "c"};
    console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
    
    // 使用Array.forEach输出属性名和属性值
    Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
      console.log(val + " -> " + obj[val]);
    });
    // 输出
    // 0 -> a
    // 1 -> b
    // 2 -> c
    
    //不可枚举属性
    var my_obj = Object.create({}, {
      getFoo: {
        value: function() { return this.foo; },
        enumerable: false
      }
    });
    my_obj.foo = 1;
    
    console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

      正如:MDN上所述,该方法返回的是对象自身的可枚举与不可枚举属性,即返回的是一个数组。并且在查阅《JavaScript高级程序设计》这本书籍的时候,却发现了一个问题。

    function Person(){
    
    }
    
    Person.prototype.name = 'asfd'
    Person.prototype.age = 15
    Person.prototype.sayName = function () {
    console.log(this.name)
    }
    var keys = Object.getOwnPropertyNames(Person.prototype) console.log(keys) 
    // 书籍中表述keys返回的是 ['constructor', 'name', 'age', 'sayName']
    // 但是当将Person.property设置一个以对象字面量形式创建的对象时,就不再返回constructor. 书籍中已经解释此时的constructor不再指向Person
    // 于是,我真的操作了一遍才发现,真的如此
    // 实例如下:
    function Person(){ } Person.prototype = { name: 'zwj', age: 21, say: function () { console.log('say') } }
    var keys = Object.getOwnPropertyNames(Person.property)
    console.log(keys)
    // 此时返回的 ['name','age','sayName']

      我根据书中理解如下:设置一个以对象字面量形式创建的对象,虽然结果相同,但是constructor不再指向Person,这就涉及到原型链了

      首先,每个构造函数被创建的时候,同时就创建了一个构造函数对应的原型对象,即: 构造函数.prototype 

      这个对象就会自动获得一个constructor属性,这个属性就是该对象指向构造函数的指针,你也可以试试输出: Person.prototype    Person.prototype.constructor     Person.prototype.constructor.prototype 等等,就会发现形成了一个闭环...

      这里我们使用的语法去接收属性值,本质上默写了prototype对象,这时候,改写的对象默认的constructor指向为Object构造函数,毕竟函数也是对象,在JS中一切皆为对象...

      所以如果我们通常为了在原型上进行大量的属性写入,就必须对这部分操作进行注意,需要在使用设置对象字面量方式之后手动为其添加constructor属性的指向,这样做的目的就是为了确保通过该属性能够访问到适当的值...

      当然你会觉得这样设置并不是完美,毕竟对于constructor这个属性,他应该是不可枚举的,此时,却是可枚举的,这是就需要我们使用Object.defineProperty()进行相应的设置.相应的代码如下:

    function Person(){
    }
    // 此时重写了prototype对象 constructor指向Object
    Person.prototype = {
      name: 'Nick',
      age: 15,
      sayName: function(){
        consolelog(this.name)
      }  
    }
    // 对constructor进行设置修改
    Object.defineProperty(Person.prototype, 'constructor', {
       enumerable: false,   // 设置是否可枚举  false为不可枚举
       value: Person         // 设置值为Person
    })
    //可以通过definePrototype进行更改数据属性的共有6个,其余4个分别为:
    // configurable  ----------> 表示是否可以通过delete进行删除 默认为true
    // writable        ----------> 表示是否可以修改属性的值 默认为true
    // get ----------> 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
    // set --------> 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。

      

      总结: 在进行创建构造函数的时候,以前习惯只是将constructor直接写在重写的prototype对象中,但是却忽略了其中最重要的一条信息,那就是constructor属性本身是不可枚举的属性,还需要更深一层的操作去设置constructor.看问题不能只看表面,更应该注重于内在...

  • 相关阅读:
    『高性能模型』卷积复杂度以及Inception系列
    『高性能模型』轻量级网络梳理
    『计算机视觉』YOLO系列总结
    利用Azure Functions和k8s构建Serverless计算平台
    我如何通过K8S开发认证(CKAD)考试
    对Windows桌面应用程序进行UI自动化测试
    Service Fabric是什么?
    如何把遗留的Java应用托管在Service Fabric中
    如何在本地数据中心安装Service Fabric for Windows集群
    当TFS/VSTS遇上Power BI
  • 原文地址:https://www.cnblogs.com/gxlself/p/9121090.html
Copyright © 2011-2022 走看看