JS创建对象几种不同方法详解_javascript技巧

本文介绍了几种js创建对象的方法,分享给大家供大家参考,具体内容如下

1、工厂模式

弊端:没有解决对象的识别问题,即怎么知道一个对象的类型。

2、构造函数模式

 

与工厂模式相比:
1、没有显式的创建对象
2、直接将属性和方法赋给了this对象
3、没有return语句
要创建person的实例,必须使用new操作符,以这种方式调用构造函数实际上会经历4个步骤:
1、创建一个新对象
2、将构造函数的作用域赋给新对象
3、执行构造函数中的代码
4、返回新对象
创建自定义的构造函数可以将它的实例标识为一种特定的类型。
构造函数的缺点:
每个方法都有在每个实例上重新创建一遍。person1和person2都有一个sayName()的方法,但两个方法不是同一个Function实例。不同实例上的同名函数是不相等的。
创建两个完成同样任务的Function实例没有必要,而且还有this对象在,不需要在执行代码前就把函数绑定在特定对象上,可以像下面这样。

 

把sayName属性设置成全局的sayName函数,这样,由于sayName包含的是一个指向函数的指针,因此person1和person2对象就共享了同一个函数。
但是,如果对象需要定义很多方法,那么就要定义很多全局函数,自定义的引用类型也没有封装可言了。为了解决上述问题,引入原型模式。

3、原型模式

理解原型对象
我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。prototype是通过调用构造函数而创建的那个对象实例的对象原型,使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。

 

首先,解析器会问实例person1是否有name属性,如果有,就返回。
如果没有,就继续去person1的原型中搜索name属性,如果有就返回。
如果没有,再继续向person1的原型的原型中搜索。

 

isPrototypeOf()确定实例和原型对象之间的关联
console.log(Person.prototype.isPrototypeOf(person1)); //true
Object.getPrototypeOf()返回的是[[prototype]]的值
console.log(Object.getPrototypeOf(person1));
//Person {name: “Yvette”, age: 26, job: “engineer”} 返回的是Person的原型对象。
console.log(Object.getPrototypeOf(person1) === Person.prototype)//true
console.log(Object.getPrototypeOf(person1).name);//”Yvette”
hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中,只有给定属性存在于实例中,才会返回true。
console.log(person1.hasOwnProperty(“name”));//false
原型与in操作符
有两种方式使用in操作符:单独使用和在for-in循环中使用。单独使用时,in操作符会在通过对象能够访问给定属性时返回true,无论该属性在于实例中还是原型中。
使用for in循环,返回的是所有能够通过对象访问的、可枚举的属性,其中既包括实例中的属性,也包括存在于原型中的属性。如果实例中的属性屏蔽了原型中不可枚举的属性,那么也会返回。IE9之前的版本实现上有一个Bug,屏蔽不可枚举属性的实例属性不会在for-in中返回。

 

在IE9之前的吧按本中没有log信息。尽管person实例中的toString()方法屏蔽了原型中的不可 枚举的toString();
原型简写

 

这导致了person1.constructor不再指向Person,而是指向了Object。如果constructor很重要,则需要特意将其设为适当的值,如:

 

但是这种方式会导致constructor属性变成可枚举。
如果想设置为不可枚举的(默认不可枚举),可以使用Object.defineProperty(Person.prototype, “constructor”, {
enumerable: false,
value: Person
});
原型的动态性
由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来。
如果重写整个原型对象,情况就不一样了。调用构造函数时会为实例添加一个指向最初原型的[[prototype]]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。实例中的指针仅指向原型,而不指向构造函数。

 

person.prototype指向的是原本的原型对象,而不会指向新的原型对象。
原型对象的问题
原型模式最大问题是由其共享的本性所导致的。
对于包含引用类型值的属性来说,问题较为突出

 

本意只想修改person1的friends,但是却导致person2的friends属性值也改变了。因此我们很少单独使用原型模式。

4、组合使用构造模式和原型模式

创建自定义类型的最常用的方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性,这样每个实例都有自己的一份实例属性的副本,又同时共享着对方法的引用,最大限度的节省了内存。
 

除了以上几种方式以外,另外还有动态原型模式,寄生构造模式和稳妥构造模式,但是鉴于使用频率较低,不再赘述。

时间: 2024-07-30 19:54:37

JS创建对象几种不同方法详解_javascript技巧的相关文章

JavaScript知识点总结(十一)之js中的Object类详解_javascript技巧

JavaScript中的Object对象,是JS中所有对象的基类,也就是说JS中的所有对象都是由Object对象衍生的.Object对象主要用于将任意数据封装成对象形式. 一.Object类介绍 Object类是所有JavaScript类的基类(父类),提供了一种创建自定义对象的简单方式,不再需要程序员定义构造函数. 二.Object类主要属性 1.constructor:对象的构造函数. 2.prototype:获得类的prototype对象,static性质. 三.Object类主要方法 1

JS中的二叉树遍历详解_javascript技巧

二叉树是由根节点,左子树,右子树组成,左子树和友子树分别是一个二叉树. 这篇文章主要在JS中实现二叉树的遍历. 一个二叉树的例子 var tree = { value: 1, left: { value: 2, left: { value: 4 } }, right: { value: 3, left: { value: 5, left: { value: 7 }, right: { value: 8 } }, right: { value: 6 } } } 广度优先遍历广度优先遍历是从二叉树的

vue.js+boostrap项目实践(案例详解)_javascript技巧

一.为什么要写这篇文章 最近忙里偷闲学了一下vue.js,同时也复习了一下boostrap,发现这两种东西如果同时运用到一起,可以发挥很强大的作用,boostrap优雅的样式和丰富的组件使得页面开发变得更美观和更容易,同时vue.js又是可以绑定model和view(这个相当于MVC中的,M和V之间的关系),使得对数据变换的操作变得更加的简易,简化了很多的逻辑代码. 二.学习这篇文章需要具备的知识 1.需要有vue.js的知识 2.需要有一定的HTML.CSS.JavaScript的基础知识 3

在Node.js中使用Javascript Generators详解_javascript技巧

Generators是Javascript的一种协同程序( coroutine 简称:协程)风格,是指那些可以在执行时暂停然后又恢复的函数,该函数是在functi配以星号符号形式如function* ,函数内有些特征关键词如yield 和yield*. function* generatorFn () { console.log('look ma I was suspended') } var generator = generatorFn() // [1] setTimeout(functio

JS插件overlib用法实例详解_javascript技巧

本文实例讲述了overlib用法.分享给大家供大家参考,具体如下: overLIB 是一个生成提示框与弹出菜单等页面效果的一段非常优秀的JS代码. 它可以简单的通过设置一些参数或命令来改变弹出页面的款式.皮肤与形状,不但如此,它还提供了非常简单的扩展功能,来足客户的不同需求. overLIB 使用非常的简单. 一.在<head></head> 标签内添加: 复制代码 代码如下: <script type="text/javascript" src=&quo

JS组件Bootstrap Table布局详解_javascript技巧

Bootstrap 提供了一个清晰的创建表格的布局.下表列出了 Bootstrap 支持的一些表格元素: 表格类下表样式可用于表格中: <tr>, <th> 和 <td> 类下表的类可用于表格的行或者单元格: 基本的表格 如果您想要一个只带有内边距(padding)和水平分割的基本表,请添加 class .table,如下面实例所示: <div class="row"> <table class="table"&

D3.js实现柱状图的方法详解_javascript技巧

D3.js介绍 D3.js 是一个基于数据操作文档JavaScript库.D3帮助你给数据带来活力通过使用HTML.SVG和CSS.D3重视Web标准为你提供现代浏览器的全部功能,而不是给你一个专有的框架.结合强大的可视化组件和数据驱动方式Dom操作.这里也可以看到它是用SVG来呈现图表的,所以使用D3.js是需要一定的SVG基础的. 如何用D3.js实现柱状图? 柱状图里面有坐标轴和柱子.然而我们还需要SVG画布来画这些东西.先把大概的画图框架搭起来,代码如下(请注意此时我在body标签里添加

js事件监听器用法实例详解_javascript技巧

本文实例讲述了js事件监听器用法.分享给大家供大家参考.具体分析如下: 1.当同一个对象使用.onclick的写法触发多个方法的时候,后一个方法会把前一个方法覆盖掉,也就是说,在对象的onclick事件发生时,只会执行最后绑定的方法.而用事件监听则不会有覆盖的现象,每个绑定的事件都会被执行.如下: window.onload = function(){ var btn = document.getElementById("yuanEvent"); btn.onclick = funct

js中this用法实例详解_javascript技巧

本文实例讲述了js中this用法.分享给大家供大家参考.具体如下: 1. 指向window 全局变量 alert(this) //返回 [object Window] 全局函数 function sayHello(){ alert(this); } sayHello(); 2. 指向该对象(在全局里面this指向window,在某个对象里面this指向该对象,在闭包里面this指向window) var user="the Window"; var box={ user:'the bo