创建对象

我们开始可以用Object构造函数或者对象字面量来快速创建对象,但使用这种方式创建多个对象时会产生大量重复代码,所以我们有了以下几种创建对象的方式。

(1)工厂模式

function createPerson(name, age,sex){ //传入的参数可以类比成送入工厂的原材料
var o = new Object();
o.name = name;
o.age = age;
o.sex = sex;
     o.sayName(){
       alert(this.name);  
     }

    return o; //返回出的对象可以类比成工厂加工完成的产品
}
var person1 = createPerson("Jack",18,"男");
var person2 = createPerson("Rose",18,"女");

当我们使用工厂模式的函数时,并不知道自己所创建的是哪一类对象,也就是说对象之间的辨识度太低,在这基础上我们有了构造函数模式。

(2)构造函数模式

function Person(name, age,sex){
this.name = name; //这里的this在创建对象时会指向新创建的对象
this.age = age;
this.sex = sex;
this.sayName = function{
alert(this.name);
}
}
var person1 = new Person("Jack",18,"男");
var person2 = new Person("Rose",18,"女");

构造函数名可以作为对象的标识符,这样对象的辨识度便上升了。

因为在定义函数时会创建新的Function实例,每一个对象实例的同名方法不是同一个Function实例,每创建一个实例会新创建一个Function实例,这无疑会增加不必要的开销。针对这一点,

我们可以把函数定义在对象外部。

function Person(name, age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}
var person1 = new Person("Jack",18,"男");
var person2 = new Person("Rose",18,"女");

但是当对象有许多方法需要定义时,我们又会发现需要在全局范围定义许多全局方法,我们就离封装代码的目的越走越远了,所以我们又有了原型模式。

(3)原型模式

function Person(){
}
Person.prototype.name = "Jack";
Person.prototype.age = 18;
Person.prototype.sex = "男";
Person.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
person1.sayName();//"Jack" 开始搜索实例的内部是否有该方法,没有的场合会开始搜索实例的原型对象
var person2 = new Person();
person2.sayName();//"Jack"
alert(person1.sayName == person2.sayName);//true

因为prototype出现了很多次我们也可以这样写

function Person(){
}
Person.prototype = {
     constructor:Person, //这里的constructor属性会变成可枚举的,默认情况下是不枚举的,可以用Object.defineProperty()
name:"Jack",
age:18,
sex:"男",
sayName:function(){
alert(this.name);
}
}

原型模式对于对象函数的共享非常友好,但因为每个对象的所有属性和方法都是公开的,当修改某个实例的属性时,其他实例的属性也会跟着一起改变,换句话说,实例彼此之间的相关性太大,所以我们可以组合使用构造函数模式和原型模式。用构造函数模式来定义实例属性,用原型模式来定义方法和共享的属性。

(4) 构造函数和原型模式组合使用

function Person(name, age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.friend = ["Jack","Rose"];
}
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}

当我们想把构造函数和原型写在一起时,可以使用动态原型模式。

(5)动态原型模式

function Person(name, age,sex){
this.name = name;
this.age = age;
this.sex = sex;
if(typeof this.sayName != 'function'){ //通过这种写法,我们不会重复定义函数
Person.prototype.sayName = function(){
alert(this.name);
};
}
}

(6)寄生构造函数模式

function Person(name, age,sex){
var o = new Object(); //在典型构造函数模式中是直接把属性保存在this,这里新创建了一个对象
o.name = name;
o.age = age;
o.sex = sex;
o.sayName = function(){
alert(this.name);
}
return o; //这里和工厂模式又有相似之处,区别在于实例的创建
} var person = new Person("Jack",18,"男"); //表面上是构造的Person对象,实际上是创建的Object类型的对象实例。
person.sayName();//"Jack"

寄生构造函数模式可以创建某个对象的加强版对象

function specialArray(){
var values = new Array();
values.push.apply(values,arguments)//将传来的参数装进数组
values.toPipedString = function(){
values.join('|');
}
return values
}
var cities = new specialArray("Shanghai","Beijing","Guangzhou");
alert(cities.toPipedString());//"Shanghai|Beijing|Guangzhou"

(7)稳妥构造函数模式

稳妥对象指的是没有共有属性,并且方法中不出现this的对象

function Person(name, age,sex){
var o = new Object();
o.sayName = function(){ //只能通过此方法改变属性值
return name;
}
return o;
}

JavaScript基础知识整理(ES5创建对象)的更多相关文章

  1. JavaScript基础知识整理

    只整理基础知识中关键技术,旨在系统性的学习和备忘. 1.在 JScript 中 null 和 undefined 的主要区别是 null 的操作象数字 0,而 undefined 的操作象特殊值NaN ...

  2. JavaScript基础知识整理(2)

    15.处理图像 注意:(1)在写js文件时,尽量将函数的声明往后写,将函数调用写在前面,这样能够使代码结构很清晰. (2)一个网页中翻转器一般超过3个,所以使用for循环减少重复使用翻转器代码的次数. ...

  3. Javascript 基础知识整理

    Javascript的作用 表单验证,减轻服务器压力 添加页面动画效果 动态更改页面内容 Ajax网络请求(异步加载数据) -它属于前端的核心,主要用来控制和重新调整DOM,通过修改DOM结构,从而达 ...

  4. JavaScript基础知识整理(1)

    粗略理解,努力入门中 1.在html中引入外部脚本:  <script src="filename.js"></script> 2.注释:  多于一行的长注 ...

  5. JavaScript基础知识整理(1)数组

    第一:创建. 1,var arr= new Array(); //数组为空.长度为0. arr[0]="apple"; arr[1]="orange"; arr ...

  6. javascript基础知识整理(不定时更新)

    1.js中真与假的定义: 真:true,非零数字,非空字符串,非空对象 假:false,数字零,空字符串,空对象(null),undefined 2.使用for循环对json进行循环操作 for(va ...

  7. Javascript基础知识总结一

    Javascript基础知识总结一 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...

  8. Kali Linux渗透基础知识整理(二)漏洞扫描

    Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网 ...

  9. 学习javascript基础知识系列第二节 - this用法

    通过一段代码学习javascript基础知识系列 第二节 - this用法 this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascr ...

  10. Kali Linux渗透基础知识整理(四):维持访问

    Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...

随机推荐

  1. 真正“搞”懂HTTPS协议16之安全的实现

    上一篇噢,我们搞明白了什么是安全的通信,这个很重要,特别重要,敲黑板!! 然后,我们还学了HTTPS到底是什么,以及HTTPS真正的核心SSL/TLS是什么.最后我们还聊了聊TLS的实现,也就是Ope ...

  2. 从 PyTorch DDP 到 Accelerate 到 Trainer,轻松掌握分布式训练

    概述 本教程假定你已经对于 PyToch 训练一个简单模型有一定的基础理解.本教程将展示使用 3 种封装层级不同的方法调用 DDP (DistributedDataParallel) 进程,在多个 G ...

  3. Element ui &多选框、输入框、下拉框、开关、上传文件

    ElementUI多选框 Checkbox 使用 <el-checkbox v-model="checked">备选项</el-checkbox> < ...

  4. Zstack私有云平台运行实践

    很高兴昨天加了大名鼎鼎的杰杰站长的微信,系统运行的怎么样,一定不能只是给力两个字完事,下面就上具体的: 经过这几年的运行费和预研经费的支持,组里除了在线的几台服务器外,慢慢离线也积攒了几台用作调试和做 ...

  5. JZOJ 2022.02.26【提高A组】模拟

    比赛总结 考场 \(T1,T2\) 思想切了 然而... \(\text{T1}\) 飞行棋 当然要 \(dp\),然而发现后六格有后效性 姑且设 \(f_i\) 表示从第 \(i\) 格到终点的期望 ...

  6. SQL语句中 left join 后用 on 还是 where,区别大了!

    前天写SQL时本想通过 A left B join on and 后面的条件来使查出的两条记录变成一条,奈何发现还是有两条. 后来发现 join on and 不会过滤结果记录条数,只会根据and后的 ...

  7. dotnet总结——类型系统

    包括2种大的类型: 引用类型和值类型, 放一张图说明继承层次: 一 值类型: 内置的值类型,如下 用户自定义值类型就是用户定义的枚举或者结构类型. 可空类型(Nullable<T>)属于 ...

  8. 【译】.NET 7 中的性能改进(七)

    原文 | Stephen Toub 翻译 | 郑子铭 Arm64 在.NET 7中,大量的努力用于使Arm64的代码生成与x64的代码生成一样好或更好.我已经讨论了一些与架构无关的PR,还有一些是专门 ...

  9. kubernetes client-go功能介绍

    原味地址 https://haiyux.cc/2023/02/26/k8s-client-go/ client-go是什么? client-go是Kubernetes官方提供的Go语言客户端库,用于与 ...

  10. JavaSE总结(2)

    控制语句idea.方法重载控制语句1.顺序结构从上到下从左到右依次执行2.判断结构    a.if(判断表达式){        语句体;    }    b.if(判断表达式){        语句 ...