创建对象

我们开始可以用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. R数据分析:孟德尔随机化中介的原理和实操

    中介本身就是回归,基本上我看到的很多的调查性研究中在中介分析的方法部分都不会去提混杂,都是默认一个三角形画好,中介关系就算过去了,这里面默认的逻辑就是前两步回归中的混杂是一样的,计算中介效应的时候就自 ...

  2. 【转载】JAVA - 解决:Java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

    抄:https://www.cnblogs.com/sunylat/p/13339507.html 问题原因: 高版本的JDK中不包含javax.xml.bind包了! 解决方法: 1,如果是mave ...

  3. mybatis学习日记2

    1.mybatis中的连接池 配置的位置:  主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是用来表示采用何种连接方式 mybatis连接池提供了3种方式的配置 ...

  4. STM32F4库函数初始化系列:PWM输出

    1 void _TIM4_Configuration(void) 2 { 3 /* TIM4 Configuration --------------------------------------- ...

  5. 样本熵(SampEn)的C/C++代码实现与优化

    正文 本文不介绍什么是样本熵,具体推荐看此文https://blog.csdn.net/Cratial/article/details/79742363,写的很好,里面的示例也被我拿来测试代码写的对不 ...

  6. ArcGIS Pro SDK 003 如何调用Toolbox

    1.如何调用普通的Tool ArcGIS中的Toolbox非常强大,做二次开发的时候,必不可少的会调用,在ArcObjects SDK中,每个Tool都会有自定义的类对应,例如栅格转矢量数据,定义在E ...

  7. 玫瑰花变蚊子血,自动化无痕浏览器对比测试,新贵PlayWright Vs 老牌Selenium,基于Python3.10

    也许每一个男子全都有过这样的两个女人,至少两个.娶了红玫瑰,久而久之,红的变了墙上的一抹蚊子血,白的还是床前明月光:娶了白玫瑰,白的便是衣服上沾的一粒饭黏子,红的却是心口上一颗朱砂痣.--张爱玲< ...

  8. 代码随想录算法训练营day09 | leetcode 28. 实现 strStr()

    LeetCode 28. 实现 strStr() 牢记一点:next[i] 元素表示[0,i]子串的最长相等前后缀个数,也是模式串与主串匹配不相等时模式串的下一个比较索引 分析1.0 前缀是指不包含最 ...

  9. python flask后端request获取参数的几种方式整理

    最近用 flask 写后端,将获取访问参数的几种方式总结整理一下,仅供参考 从 postman 上来看,调用后端接口传参的方式有两种,一种是 params,参数是以?a=x&b=y 的形式显示 ...

  10. 基于C++的OpenGL 04 之变换

    1. 概述 本文基于C++语言,描述OpenGL的变换 前置知识可参考: 基于C++的OpenGL 03 之纹理 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com) 笔者这里不过多描述每 ...