原型笔记

gxlself 2018-06-01 原文

原型笔记

  • 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进行更改数据属性的共有四个,其余两个分别为:
// configurable  ----------> 表示是否可以通过delete进行删除 默认为true
// writable        ----------> 表示是否可以修改属性的值 默认为true

  

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

 

发表于 2018-06-01 12:25 gxlself 阅读() 评论() 编辑 收藏

 

版权声明:本文为gxlself原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/gxlself/p/9121090.html

原型笔记的更多相关文章

  1. 有些ES6方法极简,但是性能不够好

    有些ES6方法极简,但是性能不够好 So,也许你觉得ES6让你视野大开,但是并不是性能也能跟得上~ 首先,让我 […]...

  2. JS面向对象与面向过程

    JS面向对象与面向过程 前言 面向对象编程:   就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属 […]...

  3. html+css+js 实现一个网页小demo

    js 从一个1.html跳转到另一个2.html页面并携带一定的数据 最近开始涉及js的学习,由于之前有一些h […]...

  4. ES6 ——— const

    ES6 ——— const 对于es6使用的也挺频繁,但是有些东西真的使用 […]...

随机推荐

  1. 20140213-面向对象技术概论

    到目前为止,面向对象已经是软件开发的主流。 面向对象技术拥有四大基本特性:封装、抽象、继承、多态 1)封装,是 […]...

  2. SpringBoot学习笔记(十五:OAuth2 )

    开放授权(Open Authorization,OAuth)是一种资源提供商用于授权第三方应用代表资源所有者获 […]...

  3. 骄傲的技术人,技术是你的全部吗?

    [一]  惊喜 2019年01月30日笔者发布了一篇 <自我剖析,坚持有多难?>  文章,本以为很 […]...

  4. Excel中concatenate函数的使用方法 – 神奇的旋风

    Excel中concatenate函数的使用方法 你还在为Excel中concatenate函数的使用方法而苦 […]...

  5. C#生成PDF2019

    因接口生成Pdf推送, 工作需要进行Pdf生成,但网上生成Pdf的文档好少: 1.生成Pdf需要文件路径/内容 […]...

  6. LogBack 日志等级设置无效,原因竟然是因为这个?!

    Hello,大家好,我是楼下小黑哥~ 最近被公司派去北京出差,本以为是个轻松的差事,北京一周游~ 但是没想到第 […]...

  7. 2_jQuery.ajax()属性介绍

    jQuery.ajax()属性详解$.ajax()方法中有很多属性可以供我们使用,其中很多属性都有默认值,那么这些属性都有哪些,处理的是什么事情?接下来给大家一一介绍一下1.url:要求为String类型的参数,(默认为...

  8. 神经网络中的激活函数的作用和选择

    如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容 […]...

展开目录

目录导航