js中常见的创建对象的方法
前两天好好的把高程对象那一块又读了下,顺便写点笔记。补一句:代码都测试过了,应该没有问题的。可以直接拿到控制台跑!
1.工厂模式
function person(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
}
return o;
}
var person1 = person('Nicholas', 29, 'Software Engineer');
var person2 = person('tangyuhui', 30, 'bigboss');
工厂模式解决了创建多个相似对象的问题,但是没有解决对象识别的问题(怎样知道一个对象的类型)。
2.构造函数模式
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
alert(this.name);
} ;
}
var person1 = new Person('Nicholas', 29, 'Software Engineer');
var person2 = new Person('tangyuhui', 30, 'bigboss');
相对于工厂模式,存在不同的地方是:
(1)没有显示地创建对象
(2)直接将属性和方法赋给了this对象
(3)没有return语句
注意:使用构造函数创建新实例,实际上会经历以下四个阶段:
(1)创建一个新对象
(2)将构造函数的作用域赋值给新对象(因此this指向了这个新对象)
(3)执行构造函数中的代码(为这个新对象添加属性)
(4)返回新对象(这里是没有显示地return才会返回新对象)
注意:构造函数的缺点是实例上的方法不是相等的,即不同实例上的同名函数是不相等的。
person1.sayName === person2.sayName //false
3.原型模式
function Person() {};
Person.prototype.name = 'Nicholas';
Person.prototype.age = 29;
Person.prototype.job = 'Software Engineer';
Person.prototype.sayName = function() {
alert(this.name);
} ;
var person1 = new Person();
var person2 = new Person();
person1.sayName === person2.sayName //true
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象是保存可以由特定类型的所有实例共享的属性和方法。
好处:可以让所有对象实例共享它所包含的属性和方法。
实例----原型----构造函数之间的关系如下图:

当然这里有一个更简便的写法:
function Person() {};
Person.prototype = {
constructor: Person,
name: 'Nicholas',
age: 29,
job: 'Software Engineer',
sayName: function() {
alert(this.name);
}
}
这里会有一个问题,这种方式重设constructor属性会导致它的[[Enumerable]]特性被设置为true,所以还有另外一种写法:
function Person() {};
Person.prototype = {
name: 'Nicholas',
age: 29,
job: 'Software Engineer',
sayName: function() {
alert(this.name);
}
}
Object.defineProperty(Person.prototype, 'constructor', {
enumerable: false,
value: Person
})
这里有一点要注意:如果要重写原型对象,一定要先重写后实例化,不然实例和原型之间就断了联系。类似下面的代码,会出错的:
function Person() {};
var friend= new Person();
Person.prototype = {
constructor: Person,
name: 'Nicholas',
age: 29,
job: 'Software Engineer',
sayName: function() {
alert(this.name);
}
}
friend.sayName();//Error
原理图如下:

原型对象代码量是减少了,但是它缺点也是比较突出的,问题就出在引用类型是按引用传递的。看代码
function Person(){};
Person.prototype = {
constructor: Person,
name:'Nicholas',
age: 29,
job: 'Software Engineer',
friends: ['zhangsan','lisi'],
sayName: function(){
alert(this.name);
}
}
var person1 = new Person();
var person2 = new Person();
person1.friends.push('wanger');
console.log(person1.friends); //zhangsan,lisi,wanger
console.log(person2.friends); //zhangsan,lisi,wanger
4.组合使用构造函数模式和原型模式
单独使用原型模式还是有一点问题,创建自定义类型的常见方式,就是使用构造函数模式与原型模式。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.firends = ['mayun', 'mahuateng']
}
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name)
}
}
var person1 = new Person('zhangsan', 29, '厨师');
var person2 = new Person('lisi', 30, '工程师');
person1.firends.push('wangwei');
console.log(person1.firends); //mayun, mahuateng, wangwei
console.log(person2.firends); //mayun, mahuateng
console.log(person1.sayName === person2.sayName); //true
5.动态原型模式
如果想把所有的信息封装在构造函数中,就可以使用该模式。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
if (typeof this.sayName !== 'function') {
Person.prototype.sayName = function(){
alert(this.name);
}
}
}
var friend = new Person('zhangsan', 29, '大佬');
6.寄生构造函数模式
function Person(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
}
return o;
}
var friend = new Person('zhangsan', 40, '计生办');
friend.sayName() //zhangsan
这种模式和工厂函数模式很像,只是使用new实例化对象,使用new构造函数实例化函数时会4个过程,如果没有指定返回值时,默认返回的是this,但也可以显示的return。这里就使用了该特性。这种模式不常用,会用到该模式,真的不常用。反正我没怎么用过。
7.稳妥构造函数模式
所谓稳妥对象,指的是没有公共属性,而且其他方法也不引用this,稳妥对象最合适在一些安全的环境中或者防止数据被篡改的程序中使用。
function Person(name, age, job) {
var o = new Object();
//定义私有变量和函数
//添加方法
o.sayName = function() {
alert(name);
}
return o;
}
var friend = Person('zhangsan', 40, '计生办');
friend.sayName() //zhangsan 只有该方法才能访问到name的值
这里需要注意的是寄生构造函数模式和稳妥构造函数模式创建的实例对象与构造函数没有什么关系。
js中常见的创建对象的方法的更多相关文章
- js中常见的创建对象的方法(1)
工厂模式:抽象了创建具体对象的过程 function createPerson(name, age, job){ var obj = new Object(); obj.name = name; ob ...
- js 中常见的深拷贝的方法
建议最简单的第一种 1.通过 JSON 对象实现深拷贝 this.data = JSON.parse(JSON.stringify(this.vm.$store.state.security.menu ...
- JS 中常见数组API使用方法(join、concat、slice、splice、reverce)
刚接触前端不久,个人觉得学习程序还是需要经常总结的.下面是我的一些知识的归纳总结,如果哪里说得不对的还请各位大神指点! 1.to str (1)String(arr)将数组中的每个元素转为字符串并用逗 ...
- JS中常见的几种继承方法
1.原型链继承 // 1.原型链继承 /* 缺点:所有属性被共享,而且不能传递参数 */ function Person(name,age){ this.name = name this.age = ...
- js中常见的问题
js中常见的问题 原文链接 1.js获取select标签选中的值 原生js var obj = document.getElementByIdx_x(”testSelect”); //定位id var ...
- JS中常见算法问题
JS中常见算法问题 1. 阐述JS中的变量提升(声明提前) 答:将所有的变量提升当当前作用域的顶部,赋值留在原地.意味着我们可以在某个变量声明前就使用该变量. 虽然JS会进行变量提升,但并不会执行真正 ...
- js中json法创建对象(json里面的:相当于js里面的=)
js中json法创建对象(json里面的:相当于js里面的=) 一.总结 json里面的:相当于js里面的= 4.json创建js对象解决命名冲突:多个人为同一个页面写js的话,命名冲突就有可能发生, ...
- JS中常见的几种报错类型
1.SyntaxError(语法错误) 解析代码时发生的语法错误 var 1a; //Uncaught SyntaxError: Invalid or unexpected token 变量名错误 c ...
- 判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解
提醒大家,Object.prototype.toString().call(param)返回的[object class]中class首字母是大写,像JSON这种甚至都是大写,所以,大家判断的时候可以 ...
随机推荐
- FileStream 和StreamWriter 一起用时
StreamWriter Flush 即可. FileStream Flush 无用.
- oracle 恢复备份
select * from dbconninfo update dbconninfo set url = 'jdbc:oracle:thin:@(description=(address_list=( ...
- debian之apt源
美国的 deb http://ftp.us.debian.org/debian stable main contrib non-freedeb-src http://ftp.us.debian.org ...
- jq 获取name值一样的数组
<input type="text" value="" name="wid"/><input type="tex ...
- Javascript作用域学习笔记(三)
看完<你不知道的javascript>上,对作用域的新的理解(2018-9-25更) 一.学习笔记: 1.javascript中的作用域和作用域链 + 每个函数在被调用时都会创建一个 ...
- VMware新建虚拟机
VMware作为一个非常便捷的虚拟机软件,学会简单的使用方法,对试验非常有帮助. 1. 打开VM,选择“创建新的虚拟机” 2. 选择典型: 3. 选择稍后选择安装源: 4. 选择Linux,并选择Li ...
- [转载] ./configure,make,make install的作用
1.configure,这一步一般用来生成 Makefile,为下一步的编译做准备,你可以通过在 configure 后加上参数来对安装进行控制,比如代码:./configure –prefix=/u ...
- thinkphp 5.0手记
场景配置,可配置多个数据库,按需求加载 数组合并:array_merge();键名相同后面覆盖前面 array_merge_recursive();键名相同,键值合并 对与http://localho ...
- 编译遇到make mrmroper问题
]: Entering directory `/home/share/project/ql-ol-sdk/ql-ol-kernel' ]: Entering directory `/home/shar ...
- Web API 源码剖析之全局配置
Web API 源码剖析之全局配置 Web API 均指Asp.net Web API .本节讲述的是基于Web API 系统在寄宿于IIS. 本节主要讲述Web API全局配置.它是如何优雅的实现 ...