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这种甚至都是大写,所以,大家判断的时候可以 ...
随机推荐
- linux sh文件提示 no such file or directory
Linux执行.sh文件,提示No such file or directory的问题的解决方法 12-06-28 16:59作者:love__coder Linux执行.sh文件,提示No such ...
- 如何判断事务是否完成,SqlTransaction
SqlConnection sconn = null; SqlCommand scmd = null; SqlTransaction strans = null; try { string sqlIn ...
- bzoj2763 飞行路线
Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...
- [转]SQL Server 中 Cast 与 Convert
两者都用于:将一种数据类型的表达式转换为另一种数据类型的表达式. 安装有 Sql Server 2008 时可以浏览:ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.zh-C ...
- 为什么 JVM 不用 JIT 全程编译
从知乎扣出来的内容 https://www.zhihu.com/question/37389356 作者:RednaxelaFX链接:https://www.zhihu.com/question/37 ...
- RmNet,CDC-ECM ,NDIS,RNDIS区别
RmNet和CDC-ECM区别:更像是两种拨号方式的区别,RmNet获取公网IP,ECD-ECM获取局域网IP. 在高通平台上,rmnet driver 和标准的CDC-ECM是有区别的,rmnet ...
- 第13章 TCP编程(2)_TCP的连接和关闭过程
4. TCP的连接和关闭过程 4.1 TCP连接的三次握手和四次挥手 (1)三次握手 ①第1次握手:建立连接.客户端发送连接请求报文段(SYN=1,sequence Number=x):然后客户端进入 ...
- Hadoop2.0的基本构成总览
Hadoop1.x和Hadoop2.0构成图对比 Hadoop1.x构成: HDFS.MapReduce(资源管理和任务调度):运行时环境为JobTracker和TaskTracker: Hadoop ...
- 省市县_me
# question 11import astfrom functools import reduce def file_read(): with open('D:\\pytharm\\ji ...
- ubuntu 命令汇总
1.linux添加全局变量 //查看当前的全局变量 echo $PATH //打开bashrc 文件,在最后面添加需要 加入的目录路径 vi ~/.bashrc //例如: export PATH=$ ...