JS创建对象篇
JS创建对象篇
Object构造函数创建
var person = new Object();
person.name = "Tom";
person.age = 10;
person.sayName = function(){
alert(this.name);
}
对象字面量
var person = {
name : "Tom",//注意这边是以“,"分隔,而不是”;"
age : 10,
sayName : function(){
alert(this.name);
}
这两种创建对象的方式都比较简便,可以用来创建单个对象。但是如果使用一个接口创建多个对象时会产生大量的重复代码。
工厂模式
function createPerson(name,age)
{ var o = new Object();//显示的创建一个对象
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name);
}
return o;//返回对象
}
var person1 = createPerson("Tom",10);
var person2 = createPerson("Jack",9);
工厂模式抽象了创建具体对象的过程这样我们就可以传入参数创建多个对象了。但是没有解决对象的识别问题
构造函数模式
function Person(name,age)
{
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var person1 = new Person("Tom",10);
var person2 = new Person("Jack",9);
//对象构造函数(constructor属性)都指向Person
console.log(person1.constructor == Person);//true
//用instanceOf来检测类型
console.log(person1 instanceOf Object);//true
console.log(person2 instanceOf Person);//true
构造函数和普通函数的区别只是调用的方式有所差别,任何函数,只要new操作符来调用的话都作为构造函数(this的绑定规则),但是构造函数模式也存在问题:每个方法都要在每个实例上重新创建一遍。
console.log(person1.sayName == person2.sayName);//false
原型模式
我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象
function Person(){}
Person.prototype.name = "Tom";
Person.prototype.age = 10;
Person.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
person1.sayName();//Tom
var person2 = new Person();
person2.sayName();//Tom
console.log(person1.sayName == person2.sayName);//true
跟构造函数模式不同,添加在prototype中的所有属性和方法都是共享的,也就是说person1和person2访问的都是同一组属性和同一个方法

每当代码读取某个属性(eg:alert(person1.job))的时候,都会执行一次搜索,目标是具有给定名字的属性,首先从对象实例本身开始,如果找到该属性则返回该属性的值,如果没有找到,则继续在原型链上向上查找,直到找到该属性停止,如果查找到原型链顶部,但是仍然没有找到指定的属性,就会返回 undefined;
对某个属性赋值(修改)(eg:person1.job="teacher")的时候,如果job存在于person1中,便会修改该属性的值。如果不在该person1中,则向原型链上查找但是这时候需要分析:
如果在原型链上找到了job,并且没有被标记为(writable:false),那么会在person1上添加一个名为job的新属性并设置它的值,这就是屏蔽属性。
如果在原型链上找到了job,但是它被标记为(writable:false),那么无法修改已有属性或是在person1上创建属性屏蔽,并且在严格模式下运行的话,代码会抛出一个错误,在非严格模式下,忽略该条语句。
如果在原型链上找到了job并且他是一个setter,那么一定会调用这个setter,job不会添加到person1上,也不会重新定义job这个setter。
如果查找到原型链顶部,但是仍然没有找到指定的属性,那么这条语句(person1.job="teacher"),便会在person1中添加一个新的属性并设置它的值。更简单的原型语法
function Person(){}
Person.prototype = {
name : "Tom",
age : 10,
sayName : function(){
alert(this.name);
}
};
这里我们重写了原型对象,但是constructor属性不在指向Person了(指向Object)
var person3 = new Person();
console.log(person3.constructor == Person);//false
console.log(person3.constructor == Object);//true
所以如果constructor属性的值很重要,那就要特意设置它的值
function Person(){}
Person.prototype = {
name : "Tom",
age : 10,
sayName : function(){
alert(this.name);
}
};
Object.defineProperty(Person.prototype,"constructor",
{
enumerable:false,
value:Person
});
//如果直接在对象中添加,会被枚举出来。
构造函数模式和原型模式的组合
构造函数模式用来定义实例属性(非共享),原型模式用来定义共享的属性或方法(共享)
function Person(name,age)
{
this.name = name;
this.age = age;
this.frieds = ["Jack","Sam"];
}
Person.prototype = {
sayName : function(){
alert(this.name);
}
}
Object.defineProperty(Person.prototype,"constructor",
{
enumerable:false,
value:Person
});
寄生构造函数模式
如果在前面的集中模式都不适用的情况下,可以使用寄生构造函数模式。
function Person(name,age)
{ var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name);
}
return o;
}
var person1 = new Person("Tom",10);
除了调用是用new操作符之外,跟工厂模式一模一样,建议可以使用其他模式的情况,不要使用这种模式
稳妥构造函数模式
稳妥,指的是没有公共属性,而且其他方法也不引用this的对象
function Person(name,age)
{ var o = new Object();
//可以在这里定义私有变量和函数
//除了sayName()方法外没有别的方式可以访问其数据成员
o.sayName = function(){
alert(name);
}
return o;
}
var person1 = new Person("Tom",10);
JS创建对象篇的更多相关文章
- js学习篇1--数组
javascript的数组可以包含各种类型的数据. 1. 数组的长度 ,直接用 length 属性; var arr=[1,2,3]; arr.length; js中,直接给数组的length赋值是会 ...
- 1. web前端开发分享-css,js入门篇
关注前端这么多年,没有大的成就,就入门期间积累了不少技巧与心得,跟大家分享一下,不一定都适合每个人,毕竟人与人的教育背景与成长环境心理活动都有差别,但就别人的心得再结合自己的特点,然后探索适合自己的学 ...
- 2. web前端开发分享-css,js进阶篇
一,css进阶篇: 等css哪些事儿看了两三遍之后,需要对看过的知识综合应用,这时候需要大量的实践经验, 简单的想法:把qq首页全屏另存为jpg然后通过ps工具切图结合css转换成html,有无从下手 ...
- 使用js创建对象
1.js创建关键字 //使用 New 关键字 function person(name,age){ this.name=name; this.age=age; } $(function(){ var ...
- web前端开发分享-css,js入门篇(转)
转自:http://www.cnblogs.com/jikey/p/3600308.html 关注前端这么多年,没有大的成就,就入门期间积累了不少技巧与心得,跟大家分享一下,不一定都适合每个人,毕竟人 ...
- web前端开发分享-css,js进阶篇
一,css进阶篇: 等css哪些事儿看了两三遍之后,需要对看过的知识综合应用,这时候需要大量的实践 经验, 简单的想法:把qq首页全屏另存为jpg然后通过ps工具切图结合css转换成html,有无 从 ...
- Chrome下的语音控制框架MyVoix.js使用篇(四)
在上一篇博文中,我为大家介绍了myvoix.js中的smart learning模块,以及何如使用该功能.(myvoix.js的源码地址会在每一篇文章末尾放出) 文本将拓展 Chrome下的语音控制框 ...
- css,js工具篇
4. web前端开发分享-css,js工具篇 web前端开发乃及其它的相关开发,推荐sublime text, webstorm(jetbrains公司系列产品)这两个的原因在于,有个技术叫emm ...
- javascript(js)创建对象的模式与继承的几种方式
1.js创建对象的几种方式 工厂模式 为什么会产生工厂模式,原因是使用同一个接口创建很多对象,会产生大量的重复代码,为了解决这个问题,产生了工厂模式. function createPerson(na ...
随机推荐
- Sublime Text3安装JsHint
介绍 Sublime Text3使用jshint依赖Nodejs,SublimeLinter和Sublimelinter-jshint. NodeJs的安装省略. 安装SublimeLinter Su ...
- GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级
一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...
- [linux]阿里云主机的免登陆安全SSH配置与思考
公司服务器使用的第三方云端服务,即阿里云,而本地需要经常去登录到服务器做相应的配置工作,鉴于此,每次登录都要使用密码是比较烦躁的,本着极速思想,我们需要配置我们的免登陆. 一 理论概述 SSH介绍 S ...
- Tcp/ip 报文解析
在编写网络程序时,常使用TCP协议.那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送.下面我们来看看几种协议头的构成 一 .Ethe ...
- HTML块级元素
前面的话 在HTML5出现之前,人们一般把元素分为块级.内联和内联块元素.本文将详细介绍HTML块级元素 h 标题(Heading)元素有六个不同的级别,<h1>是最高级的,而&l ...
- 谈谈JS的观察者模式(自定义事件)
呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...
- C++ 事件驱动型银行排队模拟
最近重拾之前半途而废的C++,恰好看到了<C++ 实现银行排队服务模拟>,但是没有实验楼的会员,看不到具体的实现,正好用来作为练习. 模拟的是银行的排队叫号系统,所有顾客以先来后到的顺序在 ...
- 【JavaScript】innerHTML、innerText和outerHTML的用法区别
用法: <div id="test"> <span style="color:red">test1</span> tes ...
- Mysql - 数据库操作
之前介绍了数据库的增删改查, 发现忘记了数据库的一些基本操作, 比如建库, 建表, 改表等等. 那这里就来小结一下数据库sql形式的基本操作. 一.库操作 1. 建库 在建库之前, 可能需要看一下, ...
- SQL面试笔试经典题(Part 1)
本文是在Cat Qi的原贴的基础之上,经本人逐题分别在MySql数据库中实现的笔记,持续更新... 参考原贴:http://www.cnblogs.com/qixuejia/p/3637735.htm ...