[js高手之路]构造函数的基本特性与优缺点
上文,通过基本的对象创建问题了解了构造函数,本文,我们接着上文继续了解构造函数的基本特性,以及优缺点.
每个对象上面都有一个constructor属性( 严格意义上来说,是原型上的,对象是通过查找到原型找到 constructor属性 ).后面讲到原型的时候,我会用示意图的方式说明
1 function CreateObj(uName) { 2 this.userName = uName; 3 this.showUserName = function () { 4 return this.userName; 5 } 6 } 7 var obj1 = new CreateObj('ghostwu'); 8 var obj2 = new CreateObj('卫庄'); 9 console.log( obj1.constructor === CreateObj ); //true 10 console.log( obj2.constructor === CreateObj ); //true
默认情况下,对象的constructor等于实例化对象的构造函数, constructor最初的作用是用来标识对象的,但是并不是特别准确,因为constructor能被修改,
识别对象一般用instanceof关键字.
什么是instanceof?
要理解这个关键字,需要搞清楚原型链,这里,我提前把他放出来
//假设instanceof运算符左边是L,右边是R L instanceof R //instanceof运算时,通过判断L的原型链上是否存在R.prototype L.__proto__.__proto__ ..... === R.prototype ? //如果存在返回true 否则返回false
注意:instanceof运算时会递归查找L的原型链,即L.__proto__.__proto__.__proto__.__proto__...直到找到了或者找到顶层为止。
所以一句话理解instanceof的运算规则为:
instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型。
console.log( obj1 instanceof Object ); //true console.log( obj2 instanceof Object ); //true console.log( obj1 instanceof CreateObj ); //true console.log( obj2 instanceof CreateObj ); //true
obj1,obj2之所以是Object的实例,因为所有对象继承自Object
借用构造函数
一个空对象,可以借用现有的构造函数,完成属性和方法的复制
1 function CreateObj(uName) { 2 this.userName = uName; 3 this.showUserName = function () { 4 return this.userName; 5 } 6 } 7 var obj = new Object(); 8 CreateObj.call( obj, 'ghostwu' ); 9 console.log( obj.userName ); //ghostwu 10 console.log( obj.showUserName() ); //ghostwu
构造函数的优点与缺点
优点就是能够通过instanceof识别对象,缺点是每次实例化一个对象,都会把属性和方法复制一遍
1 var obj1 = new CreateObj('ghostwu'); 2 var obj2 = new CreateObj('卫庄'); 3 4 console.log( obj1.showUserName === obj2.showUserName ); //false
从以上执行结果,可以看出obj1.showUserName和obj.showUserName不是同一个【在js中,引用类型比较的是地址, 函数是一种引用类型】,而是存在两个不同
的内存地址,因为每个对象的属性是不一样的,这个没有什么问题,但是方法执行的都是一样的代码,所以没有必要复制,存在多份,浪费内存.这就是缺点
怎么解决构造函数的方法复制多次的问题?
1 function CreateObj(uName) { 2 this.userName = uName; 3 this.showUserName = showUserName; 4 } 5 function showUserName (){ 6 return this.userName; 7 } 8 var obj1 = new CreateObj('ghostwu'); 9 var obj2 = new CreateObj('卫庄'); 10 console.log( obj1.showUserName === obj2.showUserName ); //true
把对象的方法指向同一个全局函数showUserName, 虽然解决了多次复制问题,但是全局函数非常容易被覆盖,也就是大家经常说的污染全局变量.
比较好的解决方案?
通过原型(prototype)对象,把方法写在构造函数的原型对象上
1 function CreateObj(uName) { 2 this.userName = uName; 3 } 4 CreateObj.prototype.showUserName = function(){ 5 return this.userName; 6 } 7 var obj1 = new CreateObj('ghostwu'); 8 var obj2 = new CreateObj('卫庄'); 9 console.log( obj1.showUserName === obj2.showUserName ); //true
什么是原型对象,以及原型链?且听下回分解
相关文章
- Js apply 方法 详解
- Html Table用JS导出excel格式问题 导出EXCEL后单元格里的000412341234会变成412341234 7-14 会变成 2018-7-14(7月14) 自定义格式 web利用table表格生成excel格式问题 js导出excel增加表头、mso-number-format定义数据格式 数字输出格式转换 mso-number-format:"@"
- 工作总结 js 选择器选择多条元素 支持一起设置他们属性 $("#edumes input[type='radio']").prop("checked", false);
- js,jq滚动监听,切换等常用JS代码
- JS基础 基本类型
- 【Vue/js】Js中执行变量中的命令语句,也就是所谓的宏替换(很实用的例子)
- 【JavaScript】JS中暂停几秒再往下执行!
- JS访问数据库[非Node.js]
- JS LeetCode 566. 重塑矩阵题解分析,数组降维的几种方式
- JS 本地储存 【详细】
- JS模式:jq中简单的模式--》采摘自js设计(tomxu_version)
- JS模式-基本的单例模式
- Node.js Express 框架
- JS教程之使用 P5.js 构建一个贪吃蛇游戏(教程含源码)
- CSS实现常用组件特效(不依赖JS)
- js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素
- JS 将数字字符串数组转为 数字数组 (互换),js获取数组对象中 某一个key的值,js判断一个数组是否包含另一个数组(一维数组)
- 深入理解JS函数中this指针的指向
- [js高手之路]性能优化技巧 - 缓存与函数重载实战
- 【Laya + TS + JS】SheetJS(js-xlsx)前端生成Excel表格
- JS魔法堂:精确判断IE的文档模式by特征嗅探
- js实现textarea文字输入个数统计效果
- JS的基础类型与引用类型
- 【cocos2d-js官方文档】五、Cocos2d-JS v3.0的新Action API
- 浏览器内核与JS引擎
- JQuery/JS插件 linq.js 获取所有选中行的Id
- JQuery/JS插件 json2.js
- RookeyFrame 加载 自定义JS