使用new和字面量的的方法是两种主流创建对象的方法,两种最终都能达到同样的实例化的对象,本章主要围绕new关键字来实例化一个对象并且讲一个不使用new但是完全与new实例化对象相同的例子。

在使用new后面跟一个构造函数的时候,将会返回一个新对象,

这个对象中的属性便就是new后面跟的构造函数中的this的属性

这个对象的__proto__属性指向就是new后面的构造函数的prototype属性。

prototype属性的值是一个对象,是Javascript为每一个函数内置的一个属性,也就是说,所有的函数都能成为构造函数,所以不到万不得已不要覆盖原来的值,更加不要使用基本类型覆盖prototype属性。

new可以总结为下面几个步骤:

  1. 创建一个新对象
  2. 把这个新对象的__proto__指向构造函数的prototype属性
  3. 把构造函数中的this上的属性全部添加到新对象
  4. 返回这个新对象

通过这四个步骤,返回了一个新实例化对象,牢记这四个步骤,就能轻松的模拟出new的效果,或者通过new模拟字面量的表示法。

假设现在有一个构造函数

//构造函数首字母大写并不是强烈要求,只是一种书写的规范
function Fun(){
this.a = 1;
this.b = "字符串";
this.arr = [1,2]
}
//每个函数中都内置了一个prototype属性
//可以通过console.log(Fun.prototype)打印出来看看
Fun.prototype.c = "prototype"
//不要直接覆盖prototype,就像下面这个例子
// Fun.prototype = "obj"
//但是如果非要覆盖的话,你可以这样做
// Fun.prototype = {
// constructor:Fun
// 把constructor属性指回构造函数
// 可以达到一样的效果
// }

执行上面的代码,接下来只需要 new Fun() 就可以返回一个新对象,并且这个对象里面拥有a,b,arr的属性,原型链__proto__上拥有c这个属性,它的结构是这样的

 //一些只是表示结构。不能执行
Fun { a:1,
b:"字符串",
arr:[1,2]
__proto__:{
c : "prototype",
constructor:function Fun()
__proto__: ......
}
}

但是,这并不是目的,目的是希望不通过new来得到一个新对象并且跟new出来一样的结果。

首先执行第一步(返回一个新对象):

 //通过字面量创建一个新对象
var obj = {}

得到这个对象之后把这个对象的__proto__指向prototype

//这里__proto__与prototype的值都是对象
//最终对象的原型链都将指向一个带get,set方法的超级对象
//__proto__是对象的原型链属性
//prototype是构造函数的一个属性
obj.__proto__ = Fun.prototype

然后需要把构造函数中this的属性全部拷贝到对象的中,这时可以使用call或在apply方法。

 //把obj作为第一个参数传入到call中
//这是Fun中的this就变成了obj
//Fun通过call执行之后,this中的属性就被拷贝到了obj中
Fun.call(obj)
//或在Fun.apply(obj)
//两个方法仅有的区别就是所传的参数不同。

最后打印一下obj,发现它与new出来的对象几乎没有差异

以下是完整代码

function Fun(){
this.a = 1;
this.b = "字符串";
this.arr = [1,2]
}
Fun.prototype.c = "prototype";
var obj = {};
obj.__proto__ = Fun.prototype;
Fun.call(obj)
var newObj = new Fun();
console.log(obj);
console.log(newObj);

模拟new实例化对象。的更多相关文章

  1. lua面向对象实现(实例化对象、继承、多态、多继承、单例模式)

    lua面向对象实现: 一个类就像是一个创建对象的模具.有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例.lua则没有类的概念,每个对象只能自定义行为和形态.不过,要在lua中模 ...

  2. [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别

    1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...

  3. java实例化对象的方式

    一.Java中创建(实例化)对象的五种方式  1.用new语句直接创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); ...

  4. PHP动态实例化对象并向构造函数传递参数

    在框架开发,模块化开发等场合,我们可能有一种需求,那就是在PHP运行时动态实例化对象. 什么是动态实例化对象呢?我们先来看一下PHP有一种变量函数(可变函数)的概念,例如如下代码: function ...

  5. 用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象

    用TypeScript开发Vue--如何通过vue实例化对象访问实际ViewModel对象 背景 我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一个问题. Vue的实例化对 ...

  6. 【PHP面向对象(OOP)编程入门教程】5.如何实例化对象?

    我们上面说过面向对象程序的单位就是对象,但对象又是通过类的实例化出来的,既然我们类会声明了,下一步就是实例化对象了. 当定义好类后,我们使用new关键字来生成一个对象. $对象名称 = new 类名称 ...

  7. PHP面向对象(OOP)编程入门教程————如何实例化对象?

    我们上面说过面向对象程序的单位就是对象,但对象又是通过类的实例化出来的,既然我们类会声明了,下一步就是实例化对象了. 当定义好类后,我们使用new关键字来生成一个对象. $对象名称 = new 类名称 ...

  8. c++实例化对象

    今天看到c++实例化对象,有点懵了.Activity_Log the_log (theLogPtr, Tree->GetBranch());这是那一段小代码,开始没看懂.java看习惯了总喜欢n ...

  9. 1、c#中可以有静态构造方法,而java中没有,例如在单例模式中c#可以直接在静态构造中实例化对象,而java不可以

    1.c#中可以有静态构造方法,而java中没有,例如在单例模式中c#可以直接在静态构造中实例化对象,而java不可以

随机推荐

  1. 关于C++的子类指针指向父类

    基类指针引用派生类对象 用基类指针引用一个派生类对象,由于派生类对象也是基类的对象,所以这种引用是安全的; 但是只能引用基类成员. 若试图通过基类指针引用那些只在派生类中才有的成员,编译器会报告语法错 ...

  2. set global read_only=0; 关闭只读,可以读写 set global read_only=1; 开始只读模式

    mysql> set global read_only=0; Query OK, 0 rows affected (0.00 sec) mysql> show variables like ...

  3. 令牌桶在数据通信QoS流量监管中的应用

    令牌桶(Tocken Bucket,以下简称TB)在流量监管(以下简称CAR)功能中完成对流量进行限速的作用.流量监管主要是应用与网络边缘,从而保证核心设备的正常数据处理. 在流量监管的处理过程中,首 ...

  4. Study notes for Sparse Coding

    Sparse Coding Sparse coding is a class of unsupervised methods for learning sets of over-complete ba ...

  5. 新书:《Liferay Portal 6.1最佳实践门户网站建设》

    新书:<Liferay Portal 6.1最佳实践门户网站建设>   <Liferay Portal 6.1门户站点建设最佳实践>是国内第一本全面介绍Liferay Port ...

  6. ClassLoader载入指定的类需注意六个细节或报ClassNotFundEception异常总结

    项目中,载入指定的类反射调用方法一直报类找不到,经过数百次的測试.对这样的问题有了一个又一次的认识,特总结.记录.分享例如以下: 1.路径中尽可能用"/"或者File.separa ...

  7. Perl 5 教程

    Perl 5 教程 http://www.cbi.pku.edu.cn/chinese/documents/perl/index.htm

  8. Eclipse用法和技巧二十:一个快速打印技巧

    调试的时候经常用到打印语句,当需要添加的说明字符串和需要打印的数值混淆到一起的时候,需要先写字符串如,"the string here is",接着再输入变量的值.这样一来一去还是 ...

  9. .NET vs JAVA

    一个同事写一个方案,让我补充下.NET和 JAVA语言的优缺点,以下是我的回复: 老X你好! 我觉得这个问题,本质上不是java和.net两个开发语言方面的比较,单纯从这两个开发语言来讲,部分伯仲,在 ...

  10. [Java聊天室server]实战之二 监听类

    前言 学习不论什么一个稍有难度的技术,要对其有充分理性的分析,之后果断做出决定---->也就是人们常说的"多谋善断":本系列尽管涉及的是socket相关的知识,但学习之前,更 ...