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这种甚至都是大写,所以,大家判断的时候可以 ...
随机推荐
- 【C#】datetimepicker里面如何设置日期为当天日期,而时间设为0:00或23:59?
今天无意中发现要根据日期查询时间,datatimepicker控件会把时间默认成当前时间(当你的控件只显示日期时),这样查询出来的出来的数据会有误差,用来下面的办法成功设置日期为当天日期,而时间设为0 ...
- redis sentinel无法启动问题
redis sentinel 正常启动 ./redis-sentinel sentinel.conf 就可以启动, 但是如果linux 操作系统(比如阿里云os)不支持ipv6,就会导致sentine ...
- 1019 General Palindromic Number (20 分)
1019 General Palindromic Number (20 分) A number that will be the same when it is written forwards or ...
- GROUP BY关键字与WITH ROLLUP一起使用
1 GROUP_CONCAT mysql> SELECT student_name, -> GROUP_CONCAT(test_score) -> FROM stud ...
- numpy的linspace函数
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False,dtype=None)[source] 文档:https://docs ...
- BCGcontrolBar(五) 对话框大小改变控件自动适应
改变控件大小 首先在 构造函数中加入 EnableLayout(); 在OnInitDialog()函数中加入 CBCGPStaticLayout* pLayout = (CBCGPStaticLay ...
- 手贱,写个call玩玩.
今天在睡觉醒时,突然感觉对call和apply有了点理解,但是又不好表达出来.就随便写几个例子. function say() { return this.role; } function Fathe ...
- HTC Vive前置摄像头API(未测试)
/*WebCamTexture:网络摄像头材质 WebCamTexture.Play() 播放: WebCamTexture.Pause() 暂停: WebCamTexture.Stop() 停止:* ...
- 【Unix网络编程】chapter2传输层:TCP,UDP和SCTP
2.1 概述 TCP:复杂,可靠的字节流协议 UDP:简单的,不可靠的数据包协议 SCTP:流控制传输协议 2.2 总图 2.3 用户数据报协议2.4 传输控制协议2.5 流控制传输协议(SCTP)2 ...
- 给iOS开发新手送点福利,简述UIImagePickerController的属性和用法
1.+(BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType; // 检查指定源是否在设备上 ...