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中将HTMLCollection/NodeList/伪数组转换成数组的代码
Jul 31 Javascript
JS教程:window.location使用方法的区别介绍
Oct 04 Javascript
js整数字符串转换为金额类型数据(示例代码)
Dec 26 Javascript
纯js实现遮罩层效果原理分析
May 27 Javascript
javascript实现日期格式转换
Dec 16 Javascript
JS实现图片的不间断连续滚动的简单实例
Jun 03 Javascript
javascript实现简易计算器
Feb 01 Javascript
Vue动画事件详解及过渡动画实例
Feb 09 Javascript
如何在Angular应用中创建包含组件方法示例
Mar 23 Javascript
js+html实现周岁年龄计算器
Jun 25 Javascript
JS如何实现网站中PC端和手机端自动识别并跳转对应的代码
Jan 08 Javascript
手写Spirit防抖函数underscore和节流函数lodash
Mar 22 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
Cappuccino 卡布其诺咖啡之制作
2021/03/03 冲泡冲煮
关于文本留言本的分页代码
2006/10/09 PHP
Zend Framework教程之Application和Bootstrap用法详解
2016/03/10 PHP
Yii2实现上下联动下拉框功能的方法
2016/08/10 PHP
thinkPHP中_initialize方法实例分析
2016/12/05 PHP
PHP code 验证码生成类定义和简单使用示例
2020/05/27 PHP
如何用javascript去掉字符串里的所有空格
2007/02/08 Javascript
生成二维码方法汇总
2014/12/26 Javascript
Jquery实现鼠标移动放大图片功能实例
2015/03/25 Javascript
js获取表格的行数和列数的方法
2015/10/23 Javascript
深入解析JavaScript编程中的this关键字使用
2015/11/09 Javascript
纯JavaScript基于notie.js插件实现消息提示特效
2016/01/18 Javascript
vue的for循环使用方法
2019/02/12 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
2019/04/17 Javascript
webpack是如何实现模块化加载的方法
2019/11/06 Javascript
python中的字典使用分享
2016/07/31 Python
Python更新数据库脚本两种方法及对比介绍
2017/07/27 Python
python tensorflow基于cnn实现手写数字识别
2018/01/01 Python
Python iter()函数用法实例分析
2018/03/17 Python
python基于C/S模式实现聊天室功能
2019/01/09 Python
Python设计模式之外观模式实例详解
2019/01/17 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
tensorboard显示空白的解决
2020/02/15 Python
Python %r和%s区别代码实例解析
2020/04/03 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
Python多线程正确用法实例解析
2020/05/30 Python
如何解决安装python3.6.1失败
2020/07/01 Python
Pycharm无法打开双击没反应的问题及解决方案
2020/08/17 Python
解决pip安装tensorflow中出现的no module named tensorflow.python 问题方法
2021/02/20 Python
使用postMessage让 iframe自适应高度的方法示例
2019/10/08 HTML / CSS
新西兰床上用品和家居用品购物网站:Adairs
2018/04/27 全球购物
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
党员民主评议自我评价
2014/10/20 职场文书
亲戚关系证明
2015/06/24 职场文书
公司处罚决定书
2015/06/24 职场文书
Pandas-DataFrame知识点汇总
2022/03/16 Python