Javascript创建对象几种方法解析

Javascript面向对象编程一直是面试中的重点,将自己的理解整理如下,主要参考《Javascript高级程序设计 第三版》,欢迎批评指正。

通过字面量形式,创建对象:

        var person_1 = {
name: "userName",
age: 20
}

工厂模式创建对象

    通过一个构造函数接收参数的方式构造对象,可无数次调用这个函数,通过改变参数构造不同的对象
         function createPerson(name,age){
var o = new Object();//创建一个空的对象 -- 原料 o.name = name;
o.age = age;
o.sayName = function(){ //给对象属性赋值 -- 加工过程
alert(this.name)
} return o; //返回加工后的对象 -- 出厂
}
var leo = createPerson('Leo',30);
leo.sayName(); //"Leo"
var cherry = createPerson('Cherry',20);
cherry.sayName(); //"Cherry"
    缺点:工厂模式创建的对象,无法判断其类型

构造函数模式:

    类似Array,Object这种原生的构造函数,我们可以通过创建自定义的构造函数,从而定义自定义对象的类型和方法
        function Person(name,age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name);
}
}
var leo = new Person('Leo',18);
var cherry = new Person('Cherry',25);
leo.sayName();
cherry.sayName();
  1. 与工厂模式对比,几点不同:没有现实的创建空对象;直接将属性和方法赋值给this;不需要return
  2. 通过New操作符创建Person对象的新实例:①创建一个新的对象 ②this指向这个新对象(作用域)③执行构造函数中的代码,对新对象添加属性和方法④返回新对象
  3. 通过instanceof检测对象类型,发现通过Person构造函数创建的对象,即使Person类的实例,又是Object对象的实例 - 创建自定义的构造函数表明可以将它的实例标识为一种特定的类型
        alert(leo instanceof Person); //true
alert(leo instanceof Object); //true 所有对象都继承自Object
  1. 区分构造函数和普通函数

    ①. 任何函数通过new操作符调用,就可做为构造函数

    ②. 自定义的构造函数,不通过new调用,与普通函数没有区别
        Person('window',100);//直接调用,相当于将Person类的属性方法直接添加到了this上
window.sayName(); //window
  1. 缺点:通过构造函数,每个方法都要在实例上重新创建一遍,每个实例的sayName方法,相当于执行this.sayName = new Function("alert(this.name)")单独创建出来的
        alert(leo.sayName==cherry.sayName);//false

原型模式:

  1. 创建的每个函数都有prototype属性,这个属性指向一个其属性和方法由某个特定类的所有实例共享的对象,利用prototype,我们就可将定义对象实例的信息放在原型对象中,不必在构造函数中定义。
        function Person(){} //构造函数变成空
Person.prototype.name = 'Leo';
Person.prototype.age =30;
Person.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
var person2 = new Person();
alert(person1.sayName==person2.sayName);//true 将sayName方法定义在Person的prototype属性中,可由多个不同的实例共享
//简化写法:
function Person() { } //构造函数变成空
Person.prototype = {
name: 'Leo',
age: 30,
sayName: function () {
alert(this.name);
}
}
var person1 = new Person();
var person2 = new Person();
  1. 只要创建一个新函数,就会为该函数创建一个prototype属性,这个属性指向原型对象。在我们创建的对象person1和person2中都包含一个内部属性,该属性指向Person.prototype,因此两个实例都可以调用原型中的sayName()方法。Object.getPrototypeOf()方法可以更方便的取得一个对象的原型.
      alert(Person.prototype.isPrototypeOf(person1));//true
alert(Person.prototype.isPrototypeOf(person2));//true
alert(Object.getPrototypeOf(person1)==Object.getPrototypeOf(person2));//true
  1. 给一个对象添加一个属性,这个属性会屏蔽原型对象中存储的同名属性,通过hasOwnProperty()方法可判断是实例对象中的属性,还是原型中的属性;通过in运算符,可以判断在对象上能否找到某属性,而不区分是实例属性还是原型属性,for in循环中只会遍历可访问、可枚举的属性。
        person1.name='Nancy';
alert(person1.name);//Nancy
alert(person1.hasOwnProperty("name"));//True 实例对象上的属性
alert(person2.hasOwnProperty("name"));//false 原型中的属性
alert("name" in person1);//true
alert("name" in person2);//true
for(key in person1){
alert(`${key}:${person1[key]}`)
}
  1. 原型模式的缺点:①缺少向构造函数传递初始化参数这一环节,使得同一个对象的所有实例在默认情况下都会取得相同的属性值。②在实例中修改引用属性的值,会影响其他的实例。
        function Newperson(){
} Newperson.prototype = {
constructor : Newperson,
name:"Tony",
age:30,
job:"Developer",
friends:['Leo','Cherry'],
sayName:function(){
alert(this.name);
}
} let newPerson1 = new Newperson();
let newPerson2 = new Newperson();
alert(newPerson1.friends);//Leo, Cherry
alert(newPerson2.friends);//Leo, Cherry
newPerson1.friends.push('Mai');//friends属性引用数组在Newperson.prototype而非newPerson1中,newPerson1.friends和newPerson2.friends指向的是同一个引用
alert(newPerson1.friends);//Leo, Cherry, Mai
alert(newPerson2.friends);//Leo, Cherry, Mai
alert(newPerson1.friends === newPerson2.friends);//true

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

  1. 组合使用构造函数模式和原型模式是创建自定义类型的常见方式,构造函数用于定义实例属性,原型模式用于定义方法和共享属性。
      function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Leo","Cherry"];
} Person.prototype = {
constructor:Person,
sayName:function(){
alert(`${this.name} is a ${this.job}.`);//公共方法
}
} let person1 = new Person('Mai',18,'actor');
let person2 = new Person('Bob',25,'developer');
person1.sayName();
person2.sayName();
alert(person1.friends == person2.friends);//false friends属性在构造函数中定义,不在原型中,两个实例不会相互影响
person1.friends.push('Tony');
person2.friends.push('Melody');
alert(person1.friends);//Leo, Cherry, Tony
alert(person2.friends);//Leo, Cherry, Melody

Javascript创建对象几种方法解析的更多相关文章

  1. 创建JAVASCRIPT对象3种方法

    创建JAVASCRIPT对象3种方法 方法一:直接定义并创建对象实例 var obj = new Object();    //创建对象实例 //添加属性obj.num = 5;   //添加属性 o ...

  2. ASP.NET,C#后台调用前台javascript的五种方法

    C#后台调用前台javascript的五种方法 由于项目需要,用到其他项目组用VC开发的组件,在web后台代码无法访问这个组件,所以只好通过后台调用前台的javascript,从而操作这个组件.在网上 ...

  3. VC调用javascript的几种方法

    第一种:通过execScript调用.这种方法,虽然操作方便,但不能获取返回值.m_spHtmlDoc->get_parentWindow(&m_pHtmlWindow);VARIANT ...

  4. Java/JSP获得客户端网卡MAC地址的三种方法解析

    java/jsp获得客户端(IE)网卡MAC地址的方法大概有三种. 1.通过命令方式,在客户端执行Ipconfig 等等.(java/jsp) 2.通过ActiveX的方法.(jsp) 3.通过向13 ...

  5. C#后台调用前台javascript的五种方法小结

    第一种,OnClientClick (vs2003不支持这个方法) <asp:Button ID="Button1" runat="server" Tex ...

  6. 【转】 C#后台调用前台javascript的五种方法

    第一种,OnClientClick    (vs2003不支持这个方法)<asp:ButtonID="Button1" runat="server" Te ...

  7. 四种方法解析JSON数据

    (1)使用TouchJSon解析方法:(需导入包:#import "TouchJson/JSON/CJSONDeserializer.h") //使用TouchJson来解析北京的 ...

  8. JAVA 创建对象4种方法

    java创建对象的几种方式 博客分类: java   (1) 用new语句创建对象,这是最常见的创建对象的方法.(2) 运用反射手段,调用java.lang.Class或者java.lang.refl ...

  9. 网页中插入javascript的几种方法

    网页中插入javascript的方法常见的有两种: 一.直接使用html标记 JavaScript 可以出现在 html的任意地方.使用标记<script>…</script> ...

随机推荐

  1. Windows NT/NTLM 加密

    Hash,一般翻译为“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是散 ...

  2. fiddler工具使用

    一.安装 a) 百度fiddler ,下载, 安装 ,无脑流 二.界面介绍 a) 工具栏与状态栏 其中保存是,可以为两种形式:1.text文本形式 2.saz文件结尾数据(能被fiddler软件识别) ...

  3. 【转】Postman 使用方法详解

    1.Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等网页调试工具.今天给大家介 ...

  4. Latex新人教程

    1.LaTeX软件的安装和使用 方法A(自助):在MikTeX的官网下载免费的MikTeX编译包并安装.下载WinEdt(收费)或TexMaker(免费)等编辑界面软件并安装. 方法B(打包):在ct ...

  5. how-to-fix-fs-re-evaluating-native-module-sources-is-not-supported-graceful

    http://stackoverflow.com/questions/37346512/how-to-fix-fs-re-evaluating-native-module-sources-is-not ...

  6. ORA-01144_表空间数据文件超出最大限制

    Oracle11gR2扩展表空间报ORA-01144错误. 数据块大小为8K的数据库,单个数据文件大小限制在32GB内. 解决办法: 1.增加表空间数据文件的方式: 2.创建BIGFILE表空间:

  7. 随机带权选取文件中一行 分类: linux c/c++ 2014-06-02 00:11 344人阅读 评论(0) 收藏

    本程序实现从文件中随即选取一行,每行被选中的概率与改行长度成正比. 程序用一次遍历,实现带权随机选取. 算法:假设第i行权重wi(i=1...n).读取到文件第i行时,以概率wi/(w1+w2+... ...

  8. Kali linux 2016.2(Rolling)里安装中文输入法

    写在前面的话 关于中文输入法,实在是有太多了.当然,你也不可以不安装,(安装了增强工具即可),在windows 里输入中文,复制进去即可. 但是呢,想成为高手,还是要学会安装和使用各版本的中文输入法. ...

  9. 外文翻译 《How we decide》赛场上的四分卫

    本书导言翻译 为了能看懂这一章,先做了如下的功课: 百度百科 四分卫 国家橄榄球联盟中文站 在2002年超级碗赛场上,比赛的时间仅剩80秒,两队比分持平.新英格兰爱国者队于17码的位置执球,他们的对手 ...

  10. Windows10系统切换JDK版本(前提是装了多个版本的JDK)

    由于是直接截屏,等我回过头来整理的时候忘记了文章原来的出处, 如作者本人看到,如有侵权,请联系删除!