JS中Object对象的原型概念基础


Posted in Javascript onJanuary 29, 2018

对象概念

在 javascript 中, 一切引用类型均为对象。 如 function Foo () {} 中,Foo本身就是一个对象的引用。

创建对象方式 字面量方式 new 构造函数函数声明 Object.create

字面量对象

javascript语言级别快速创建对象的实例

var obj = {foo: 'foo', bar: 'bar'}; // Object对象字面量
var obj2 = [obj, 'foo', 'bar']; // Array数组字面量
var obj3 = /^[a-zA-Z0-9]$/; // RegExp正则字面量
var obj4 = function(){}; // Function函数字面量

new 构造函数

通过内置对象的构造函数,或者自定义的函数。 使用 new 操作符,创建一个对象,并且执行构造函数方法。

var obj = new Object();
var obj2 = new Array(1000);
var obj3 = new RegExp('^[a-zA-Z0-9]$');
var obj4 = new Function('a', 'b', 'return a + b;');

函数声明

函数声明创造的对象. 函数属于特殊的对象.

function Foo() {}
Foo instanceof Object;
Foo instanceof Function;

Object.create

传入一个对象作为返回对象的原型,创建一个新对象, 并将新对象的原型指向传入的对象中。

var foo = {
 'foo': 'foo',
 'bar': 'bar'
};
var o = Object.create(foo); // o.__proto__ = foo
console.log(o.foo); // o.__proto__.foo

使用Object.create(null) 可以返回一个字典型对象.

var o = Object.create(null);
o instanceof Object; // return false;
o.toString(); // Uncaught TypeError

对象原型

每一个对象都有一个内置的 __proto__ 属性指向构造它的函数prototype属性. 而构造函数的

prototype.constructor 则指向构造函数本生。一个对象的属性的寻找过程由以下几个部分组成:

寻找对象属性的数据描述符(writable, value)或存取描述符(getter, setter),如果查询到了,则返回 对应的值。如果查询不到,则进入第2步骤。寻找对象属性的值是否有被显示定义 (可以通过 Object.getOwnPropertyNames)检测,如果对象属性定义了,则返回定义的值。 如果没有,则进入第3步骤。寻找对象的隐藏原型__proto__对象的属性,规则同1,2步骤。如果还未找到,则重复第3步骤, 直到__proto__ 为null 为止。

具体案例如下图所示:

JS中Object对象的原型概念基础

检测对象原型

测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性

instanceof Object.prototype.isPrototypeOf

instanceof

运算符,语言级别的检测对象的原型链是否包含构造函数的原型

function Foo () {}
Foo instanceof Function; // return true
Foo instanceof Object; // return true

模拟instanceof查找对象的原型链的构造函数是否包含传入的构造函数, __proto__ 在一些特定的浏览器有暴露给用户

function Bar () {}
function isInstanceof (obj, Constructor) {
 if (obj === null) {
 return false;
 }
 // 忽略 string, number, boolean, null, undefined 类型干扰
 if (!~['object', 'function'].indexOf(typeof obj)) {
 return false;
 }

 var prototype = obj.__proto__;
 while(prototype) {
 if (prototype.constructor === Constructor) {
  return true;
 }
 prototype = prototype.__proto__;
 }
 return false;
}
isInstanceof(Bar, Function);
isInstanceof(Bar, Object);

isPrototypeOf

构造函数的原型对象自带的函数属性, 用于检测目标对象的原型链中是否存在构造函数的原型对象。

function Baz () {}
var baz = new Baz();
Baz.prototype.isPrototypeOf(baz);
Function.prototype.isPrototypeOf(baz);
Object.prototype.isPrototypeOf(baz);

获取对象原型 Object.getPrototypeOf __proto__

var o = {};
var prototype = Object.getPrototypeOf(o);
console.log(prototype === Object.prototype); // return true
// 部分浏览器有效
var o2 = {};
console.log(o2.__proto__ === Object.prototype); // return true

设置对象原型 Object.create Object.setPrototypeOf

Object.create

返回一个对象,并设置它的原型

function Foo () {}
 function Bar () {}
 Foo.prototype.foo = 'foo';
 Bar.prototype = Object.create(Foo.prototype); 
 Bar.prototype.constructor = Bar; // 修正原型链的constructor
 var o = new Bar();
 console.log(o.foo); // return foo;
 console.log(o instanceof Bar); // return true

Object.setPrototypeOf

直接设置对象的隐式原型__proto__

function Foo () {}
 Foo.prototype.name = 'foo';
 var o = Object.create(null);
 Object.setPrototypeOf(o, Foo.prototype);
 console.log(o.name); // return foo

小结

对象具有许多考验开发者的一些知识点。能够完全理解并整理出来是不容易的。后续我会针对对象的继承做个详细的介绍。感谢你对三水点靠木的支持。

Javascript 相关文章推荐
犀利的js 函数集合
Jun 11 Javascript
zeroclipboard 单个复制按钮和多个复制按钮的实现方法
Jun 14 Javascript
一个JavaScript函数把URL参数解析成Json对象
Sep 24 Javascript
jQuery循环动画与获取组件尺寸的方法
Feb 02 Javascript
原生JS和JQuery动态添加、删除表格行的方法
May 28 Javascript
JS获取当前脚本文件的绝对路径
Mar 02 Javascript
Javascript将JSON日期格式化
Aug 23 Javascript
简单实现JS上传图片预览功能
Apr 14 Javascript
node.js爬取中关村的在线电瓶车信息
Nov 13 Javascript
vue项目刷新当前页面的三种方法
Dec 04 Javascript
js笔试题-接收get请求参数
Jun 15 Javascript
JS实现百度搜索框
Feb 25 Javascript
vue.js实现只弹一次弹框
Jan 29 #Javascript
javascript trie前缀树的示例
Jan 29 #Javascript
Vue官网todoMVC示例代码
Jan 29 #Javascript
jquery动态添加以及遍历option并获取特定样式名称的option方法
Jan 29 #jQuery
Angular2 父子组件通信方式的示例
Jan 29 #Javascript
jQuery代码优化方法总结
Jan 29 #jQuery
javascript代码优化的8点总结
Jan 29 #Javascript
You might like
JS 网站性能优化笔记
2011/05/24 PHP
PHP实现时间轴函数代码
2011/10/08 PHP
JavaScript创建命名空间的5种写法
2014/06/24 PHP
php上传图片客户端和服务器端实现方法
2015/03/30 PHP
常见PHP数据库解决方案分析介绍
2015/09/24 PHP
PHP中如何使用session实现保存用户登录信息
2015/10/20 PHP
PHP MySql增删改查的简单实例
2016/06/21 PHP
php查询内存信息操作示例
2019/05/09 PHP
动态表格Table类的实现
2009/08/26 Javascript
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
学习ExtJS(二) Button常用方法
2009/10/07 Javascript
JavaScript不刷新实现浏览器的前进后退功能
2014/11/05 Javascript
js实现点击链接后延迟3秒再跳转的方法
2015/06/05 Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
2016/05/07 Javascript
jQuery EasyUI 入门必看
2016/06/03 Javascript
AngularJS入门教程之数据绑定原理详解
2016/11/02 Javascript
echarts鼠标覆盖高亮显示节点及关系名称详解
2018/03/17 Javascript
nodejs中密码加密处理操作详解
2018/03/20 NodeJs
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
vue vue-Router默认hash模式修改为history需要做的修改详解
2018/09/13 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
2018/09/14 Javascript
ES6 Generator基本使用方法示例
2020/06/06 Javascript
浅谈鸿蒙 JavaScript GUI 技术栈
2020/09/17 Javascript
Python按行读取文件的简单实现方法
2016/06/22 Python
Python2和Python3.6环境解决共存问题
2018/11/09 Python
python 多进程队列数据处理详解
2019/12/23 Python
用python制作个视频下载器
2021/02/01 Python
python 基于DDT实现数据驱动测试
2021/02/18 Python
使用CSS3的::selection改变选中文本颜色的方法
2015/09/29 HTML / CSS
科颜氏加拿大官方网站: Kiehl’s加拿大
2016/08/16 全球购物
2013年高中生自我评价
2013/10/23 职场文书
工程部经理岗位职责
2015/02/02 职场文书
MYSQL(电话号码,身份证)数据脱敏的实现
2021/05/28 MySQL
新手初学Java网络编程
2021/07/07 Java/Android
Prometheus 监控MySQL使用grafana展示
2021/08/30 MySQL
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL