创建对象

我们开始可以用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. wsl2 使用串口/usb

    wsl2串口 搜了几个方案,都不合适 网上很多人说wsl可以直接使用win的串口,com* 就对应 /dev/ttyS* 实际上这是wsl1的,wsl2官方明确表示不支持了 CH340 介绍 CH34 ...

  2. JS 计算两个时间戳相差年月日时分秒

    // JS 计算两个时间戳相差年月日时分秒 calculateDiffTime(startTime, endTime, type) { var runTime = parseInt(endTime - ...

  3. 树莓派4B安装OPENCV4.0

    参考 : https://www.pyimagesearch.com/2018/09/26/install-opencv-4-on-your-raspberry-pi/ Step #1: Expand ...

  4. cv::Mat::step详解

    1.简介 step的几个类别区分: step:矩阵第一行元素的字节数 step[0]:矩阵第一行元素的字节数 step[1]:矩阵中一个元素的字节数 step1(0):矩阵中一行有几个通道数 step ...

  5. STM32F4寄存器初始化系列:GPIO

    1 static void GPIO_Init(void) 2 { 3 4 //sound 5 GPIO_Set(GPIOB,PIN4,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO ...

  6. Win10 局域网共享文件遇到的疑难杂症通用解决策略

    win10局域网共享文件时遇到的疑难杂症类型: 1. 网络列表中不能发现别人的计算机,别人也看不到自己的计算机 启用windows功能:SMB 1.0/CIFS 文件共享支持 确保文件共享的计算机处于 ...

  7. JZOJ 7685. 【2022.10.06冲剌NOIP2022模拟】奇怪的函数(function)

    \(\text{Solution}\) 观察到关于 \(x\) 的函数在 \(n\) 个操作之后一定是这样的: 一段水平直线加上一段斜率为 \(1\) 的直线再加上一段水平直线 于是线段树维护这个分段 ...

  8. 跳板攻击之:reGeorg 代理转发

    跳板攻击之:reGeorg 代理转发 郑重声明: 本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关.倡导维护网络安全 ...

  9. Angular UI库

    1.angular 使用 bootstrap 安装bootstrap npm install bootstrap --save 安装bootstrap-icons npm i bootstrap-ic ...

  10. ansible 离线部署

    1.安装 python 环境 wget https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-2022.10-Linux-x86_64.sh s ...