JavaScript 原型链常用方法

对象属性类型

数据属性

  1. Configurable(表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性)

  2. Enumerable(表示能否通过 for-in 循环返回属性)

  3. Writable(表示能否修改属性的值)

  4. Value(这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。默认值为 undefined)

  • 把 configurable 设置为 false,表示不能从对象中删除属性。如果对这个属性调用 delete,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。一旦把属性定义为不可配置的,就不能再把它变回可配置了。此时,再调用 Object.defineProperty()方法修改除 writable 之外的特性,都会导致错误

访问器属性

  • 访问器属性不包含数据值;它们包含一对儿 getter 和 setter 函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter 函数并传入新值,这个函数负责决定如何处理数据

  • 访问器属性不能直接定义,必须使用 Object.defineProperty()来定义在不支持 Object.defineProperty() 方法的浏览器中不能修改 Configurable 和Enumerable

  1. Configurable(表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。默认值为true)

  2. Enumerable(表示能否通过 for-in 循环返回属性。对于直接在对象上定义的属性)

  3. Get(在读取属性时调用的函数。默认值为 undefined)

  4. Set(在写入属性时调用的函数。默认值为 undefined)

注意事项:

  • 共同点:数据属性 和 访问器属性均具有以下可选键值:
  1. configurable 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。

  2. enumerable 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。

  • 如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

  • 考虑特性被赋予的默认特性值非常重要,通常,使用**点运算符和Object.defineProperty()**为对象的属性赋值时,数据描述符中的属性默认值是不同的,如下例所示。

var obj = {};obj.vfrank = 1;// 等同于 :Object.defineProperty(obj, "vfrank", {value: 1,writable: true,configurable: true,enumerable: true});// 另一方面,Object.defineProperty(obj, "vfrank", { value: 1 });// 等同于 :Object.defineProperty(obj, "vfrank", {value: 1,writable: false,configurable: false,enumerable: false});
configurable enumerable value writable get set
数据属性(数据描述符) Yes Yes Yes Yes No No
访问器属性(存取描述符) Yes Yes No No Yes Yes

Object.defineProperty() 和 Object.defineProperties()

  • 定义
  1. Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象**(IE8 部分支持)**。

  2. Object.defineProperties() 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象(IE9+)。

  • IE8 是第一个实现 Object.defineProperty()方法的浏览器版本。然而,这个版本的实现存在诸多限制:只能在 DOM 对象上使用这个方法,而且只能创建访问器属性。由于实现不彻底,建议不要在 IE8 中使用 Object.defineProperty()方法

Object.getOwnPropertyDescriptor()

  • 返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性

  • 可以取得给定属性的描述符。这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称。返回值是一个对象,如果是访问器属性,这个对象的属性有 configurable、enumerable、get 和 set;如果是数据属性,这个对象的属性有 configurable、enumerable、writable 和 value

var vfrank = {};Object.defineProperties(vfrank, {_year: {value: 2019},edition: {value: 1},year: {get: function() {return this._year;},set: function(newValue) {if (newValue > 2019) {this._year = newValue;this.edition += newValue - 2019;}}}});// 数据属性var descriptor = Object.getOwnPropertyDescriptor(vfrank, "_year");console.log(descriptor.value); //2019 console.log(descriptor.configurable); //false console.log(typeof descriptor.get); //"undefined" // 访问器属性var descriptor = Object.getOwnPropertyDescriptor(vfrank, "year");console.log(descriptor.value); //undefined console.log(descriptor.enumerable); //false console.log(typeof descriptor.get); //"function"

instanceof 运算符

  • obj instanceof classConstructor

  • instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置(即:object是否属于classConstructor)

    function VFrank(name, work, age) {this.name = name;this.work = work;this.age = age;}var person = new VFrank('VFrank', 'Web engineer', 24);console.log(person instanceof VFrank); // trueconsole.log(person instanceof Object); // true

isPrototypeOf()

  • prototypeObj.isPrototypeOf(obj)

  • 用于测试一个对象是否存在于另一个对象的原型链上。在obj对象原型链上搜寻

function VFrank() {}VFrank.prototype.name = "vfrank";VFrank.prototype.age = 29;VFrank.prototype.job = "Web Engineer";var person = new VFrank();console.log(VFrank.prototype.isPrototypeOf(person));// true

Object.getPrototypeOf()

  • Object.getPrototypeOf(obj)

  • 返回指定对象的原型(内部[[Prototype]]属性的值)

function VFrank() {}VFrank.prototype.name = "vfrank";VFrank.prototype.age = 29;VFrank.prototype.job = "Web Engineer";var person = new VFrank();console.log(Object.getPrototypeOf(person));// {name: "vfrank", age: 29, job: "Web Engineer"}

hasOwnProperty()

  • obj.hasOwnProperty(prop)

  • obj对象自身属性中是否具有prop的属性

function VFrank() {}VFrank.prototype.name = "vfrank";VFrank.prototype.age = 29;VFrank.prototype.job = "Web Engineer";var person = new VFrank();console.log(person.name); //"vfrank"  来自原型链console.log(person.hasOwnProperty("name")); //false person.name = "GongGe";console.log(person.name); //"GongGe"——来自实例console.log(person.hasOwnProperty("name")); //true delete person.name;console.log(person.name); //"vfrank"——来自原型console.log(person.hasOwnProperty("name")); //false

in 操作符

function VFrank() {}VFrank.prototype.name = "vfrank";VFrank.prototype.age = 29;VFrank.prototype.job = "Web Engineer";var person = new VFrank();console.log(person.name); //"vfrank" ——来自实例console.log(person.hasOwnProperty("name")); //false console.log("name" in person); //true person.name = "GongGe";console.log(person.name); //"GongGe" ——来自实例console.log(person.hasOwnProperty("name")); //true console.log("name" in person); //true delete person.name;console.log(person.name); //"vfrank" ——来自原型console.log(person.hasOwnProperty("name")); //false console.log("name" in person); //true
  • 同时使用 hasOwnProperty()方法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中

  • IE 早期版本的实现中存在一个 bug,即屏蔽不可枚举属性的实例属性不会出现在 for-in 循环中

var obj = {toString: function() {return "Hellp VFrank";}};for (var prop in obj) {if (prop == "toString") {console.log("Found toString Hellp VFrank"); //在 IE 中不会显示(书上写的)// 真实测试IE11 edge中还是会有,使用仿真的也会出来,需要用真实版IE低版本测试下}}

getOwnPropertyNames()

  • Object.getOwnPropertyNames(obj)

  • 返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。(Object.keys()是列举可枚举属性)

  • 数组中枚举属性的顺序与通过 for…in 循环(或 Object.keys)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。

function VFrank() {}VFrank.prototype.name = "vfrank";VFrank.prototype.age = 29;VFrank.prototype.job = "Web Engineer";var person = new VFrank();console.log(Object.getOwnPropertyNames(VFrank.prototype)); // ["constructor", "name", "age", "job"]console.log(Object.keys(VFrank.prototype)); //  ["name", "age", "job"]

JavaScript 原型链常用方法相关推荐

  1. javascript原型链中 this 的指向

    为了弄清楚Javascript原型链中的this指向问题,我写了个代码来测试: var d = {d: 40};var a = {x: 10,calculate: function (z) {retu ...

  2. 深度解析JavaScript原型链

    深度解析JavaScript原型链 文章目录 深度解析JavaScript原型链 前言 JavaScript原型链,这里只分享我自己的见解 一.原型链是什么 二.心得 三图解 总结 前言 JavaSc ...

  3. JavaScript原型链污染攻击

    前言 最近在看js的时候看到p神的一篇关于js原型链污染的文章,学习一下. 下面转自p神:深入理解 JavaScript Prototype 污染攻击 还有一篇案例关于js原型链污染的ctf题:从一道 ...

  4. JavaScript 原型链和继承面试题

    JavaScript 原型链和继承问题 JavaScript 中没有类的概念的,主要通过原型链来实现继承.通常情况下,继承意味着复制操作,然而 JavaScript默认并不会复制对象的属性,相反,Ja ...

  5. 技术分享经典 javaScript原型链面试题

    技术分享 javaScript原型链 一个小题目 前置知识 变量提升和函数提升 this指针的指向 原型链是什么 new操作符的工资流程 一个小题目 今天我们部门的技术分享上出现了这样一段代码: fu ...

  6. 如何理解JavaScript原型链

    如何理解JavaScript原型链 实例对象与原型对象的关系 构造函数.原型对象和实例对象之间的关系 原型链结构图 函数在原型链中的结构 原型链的理解和总结 实例对象与原型对象的关系 构造函数.原型对 ...

  7. JavaScript原型链以及Object,Function之间的关系

    JavaScript里任何东西都是对象,任何一个对象内部都有另一个对象叫__proto__,即原型,它可以包含任何东西让对象继承.当然__proto__本身也是一个对象,它自己也有自己的__proto ...

  8. 理解JavaScript原型链

    JavaScript中的每个对象都有一个prototype属性,我们称之为原型,而原型的值也是一个对象,因此它也有自己的原型,这样就串联起来了一条原型链,原型链的链头是object,它的prototy ...

  9. JavaScript原型链的理解

    一.原型链的概念 JavaScript是一门面向对象的编程语言,JavaScript 中的所有事物都是对象,并且对象与对象之间不是彼此独立的,而是有"继承"关系的. 这种" ...

最新文章

  1. 微软和 SAP 扩展了云环境中的合作关系
  2. TiDB 官方设计文档翻译(一)
  3. python装饰器功能是冒泡排序怎么做_传说中Python最难理解的点|看这完篇就够了(装饰器)...
  4. springmvc怎么解析post_秋招跳槽,面试是拦路虎?【spring、springMVC】- 常见面试题汇总...
  5. 使用反射代理类加载器的潜在内存使用问题
  6. 服务器如何启动运行,如何在服务器系统启动或重新启动时执行命令或脚本
  7. PHP 面试时常考的文件操作函数
  8. Android学习笔记(一):Android基础
  9. 自相关函数与互相关函数
  10. 通用办公报表打印软件
  11. hive获取数据中位数函数
  12. 计算机网线怎么连接另一台电脑,教你如何用一根网线将两台电脑直连
  13. 第十一周项目一 类的继承填空
  14. 在Netbeans中搭建Android开发环境
  15. Python3.X使用Cython调用C/C++
  16. Redis的zset结构跳表
  17. cmd命令行切换目录
  18. 基于姿态估计的运动计数APP开发
  19. 软件测试之使用jmeter进行压力测试
  20. Servlet之 http://localhost:8080/ 详解

热门文章

  1. HTML DOM:replaceChild()和cloneNode()
  2. 计算几何(二维)-基本组件(1)
  3. 项目中的自定义first table第一个表--人力资源考勤表
  4. QT读取网卡列表多网卡绑定组播网卡
  5. Rk3399 Android9.0 恢复出厂设置流程
  6. 小白如何学习黑客技术?
  7. dw如何上传到远程服务器,怎么用dreamweaver链接远程的服务器站点
  8. mysql 触发器 bug_MySQL触发器不起作用
  9. 程序员什么时候该跳槽?
  10. 自动生成指定特征的数独题目(未完待续)