JS创建对象篇

  1. Object构造函数创建

 var person = new Object();
person.name = "Tom";
person.age = 10;
person.sayName = function(){
alert(this.name);
}
  1. 对象字面量

var person = {
name : "Tom",//注意这边是以“,"分隔,而不是”;"
age : 10,
sayName : function(){
alert(this.name);
}

这两种创建对象的方式都比较简便,可以用来创建单个对象。但是如果使用一个接口创建多个对象时会产生大量的重复代码。

  1. 工厂模式

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);

工厂模式抽象了创建具体对象的过程这样我们就可以传入参数创建多个对象了。但是没有解决对象的识别问题

  1. 构造函数模式

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
  1. 原型模式

我们创建的每一个函数都有一个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
});
//如果直接在对象中添加,会被枚举出来。
  1. 构造函数模式和原型模式的组合

构造函数模式用来定义实例属性(非共享),原型模式用来定义共享的属性或方法(共享)

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
});
  1. 寄生构造函数模式

如果在前面的集中模式都不适用的情况下,可以使用寄生构造函数模式。

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操作符之外,跟工厂模式一模一样,建议可以使用其他模式的情况,不要使用这种模式

  1. 稳妥构造函数模式

稳妥,指的是没有公共属性,而且其他方法也不引用this的对象

function Person(name,age)
{ var o = new Object();
//可以在这里定义私有变量和函数
//除了sayName()方法外没有别的方式可以访问其数据成员
o.sayName = function(){
alert(name);
}
return o;
}
var person1 = new Person("Tom",10);

JS创建对象篇的更多相关文章

  1. js学习篇1--数组

    javascript的数组可以包含各种类型的数据. 1. 数组的长度 ,直接用 length 属性; var arr=[1,2,3]; arr.length; js中,直接给数组的length赋值是会 ...

  2. 1. web前端开发分享-css,js入门篇

    关注前端这么多年,没有大的成就,就入门期间积累了不少技巧与心得,跟大家分享一下,不一定都适合每个人,毕竟人与人的教育背景与成长环境心理活动都有差别,但就别人的心得再结合自己的特点,然后探索适合自己的学 ...

  3. 2. web前端开发分享-css,js进阶篇

    一,css进阶篇: 等css哪些事儿看了两三遍之后,需要对看过的知识综合应用,这时候需要大量的实践经验, 简单的想法:把qq首页全屏另存为jpg然后通过ps工具切图结合css转换成html,有无从下手 ...

  4. 使用js创建对象

    1.js创建关键字 //使用 New 关键字 function person(name,age){ this.name=name; this.age=age; } $(function(){ var ...

  5. web前端开发分享-css,js入门篇(转)

    转自:http://www.cnblogs.com/jikey/p/3600308.html 关注前端这么多年,没有大的成就,就入门期间积累了不少技巧与心得,跟大家分享一下,不一定都适合每个人,毕竟人 ...

  6. web前端开发分享-css,js进阶篇

    一,css进阶篇: 等css哪些事儿看了两三遍之后,需要对看过的知识综合应用,这时候需要大量的实践 经验, 简单的想法:把qq首页全屏另存为jpg然后通过ps工具切图结合css转换成html,有无 从 ...

  7. Chrome下的语音控制框架MyVoix.js使用篇(四)

    在上一篇博文中,我为大家介绍了myvoix.js中的smart learning模块,以及何如使用该功能.(myvoix.js的源码地址会在每一篇文章末尾放出) 文本将拓展 Chrome下的语音控制框 ...

  8. css,js工具篇

    4. web前端开发分享-css,js工具篇   web前端开发乃及其它的相关开发,推荐sublime text, webstorm(jetbrains公司系列产品)这两个的原因在于,有个技术叫emm ...

  9. javascript(js)创建对象的模式与继承的几种方式

    1.js创建对象的几种方式 工厂模式 为什么会产生工厂模式,原因是使用同一个接口创建很多对象,会产生大量的重复代码,为了解决这个问题,产生了工厂模式. function createPerson(na ...

随机推荐

  1. servlet文件下载

    创建web工程servlet,新建DownloadServlet.java package com.xmyself.servlet; import java.io.File; import java. ...

  2. LeetCode: 3Sum

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

  3. PHP源码分析-变量

    1. 变量的三要素变量名称,变量类型,变量值 那么在PHP用户态下变量类型都有哪些,如下: // Zend/zend.h #define IS_NULL 0 #define IS_LONG 1 #de ...

  4. SQLServer 版本之八大方法搞清 "我是谁"

    你正在使用 SQL Server 的哪个版本? 贴士:作为一个SQL Server数据库管理者或维护.支持人员,应该会经常问自己这样一个问题:我当前SQL Server版本号是?当前版本已经有的累计更 ...

  5. MJRefresh 源码解读 + 使用

    MJRefresh这个刷新控件是一款非常好用的框架,我们在使用一个框架的同时,最好能了解下它的实现原理,不管是根据业务要求在原有的基础上修改代码,还是其他的目的,弄明白作者的思路和代码风格,会受益匪浅 ...

  6. 接口--interface

    “interface”(接口)关键字使抽象的概念更深入了一层.我们可将其想象为一个“纯”抽象类.它允许创建者规定一个类的基本形式:方法名.自变量列表以及返回类型,但不规定方法主体.接口也包含了基本数据 ...

  7. 代码的坏味道(19)——狎昵关系(Inappropriate Intimacy)

    坏味道--狎昵关系(Inappropriate Intimacy) 特征 一个类大量使用另一个类的内部字段和方法. 问题原因 类和类之间应该尽量少的感知彼此(减少耦合).这样的类更容易维护和复用. 解 ...

  8. continue break 区别

    在循环中有两种循环方式 continue , break continue 只是跳出本次循环, 不在继续往下走, 还是开始下一次循环 break  将会跳出整个循环, 此循环将会被终止 count = ...

  9. 【SAP业务模式】之ICS(六):发票输出类型

    这篇开始主要讲述发票输出类型: 首先我们新建一个发票类型,用于公司间的发票MIV,而标准的发票类型还是F2保持不变: 一.新建发票类型: 目录:SPRO-销售与分销-出具发票-开票凭证-定义出具发票类 ...

  10. TFS2013 设置签出独占锁

    转载自: http://www.cnblogs.com/zhang888/p/4280251.html