new做了什么js(new做了什么事)
JS使用new操作符创建对象的方法分析
本文实例讲述了JS使用new操作符创建对象的方法。分享给大家供大家参考,具体如下:
在编写js代码时,我们有时会需要使用函数来模拟java中的类,并用它来产生对象,在定义了一个构造函数之后我们需要使用new操作符来调用调用函数才能得到我们想要的对象。例如:
script
function
Constructor(name){
this.name
=
name
}
var
person1
=
Constructor("张三");//undefined
var
person2
=
new
Constructor("张三");//得到一个对象{name:"张三"}
console.log(person1);
console.log(person2);
/script
运行结果:
如果我们不使用new操作符调用函数,就只会简单的执行函数,并把函数的返回值赋给person1,所以上面的例子中person1的值是undefined,.
如果我们使用new操作符调用构造函数,做了哪些事情呢?
1.构造函数没有返回值
使用new操作符调用函数,会隐式的创建一个对象(我们这里称这个对象为obj),这个对象obj是连接到构造函数的原型上的,即obj会继承构造函数原型上的属性方法,并且构造函数中的this也被绑定到了这个对象上,执行完成后这个对象会被作为返回值返回。
2.构造函数有返回值(这种情况比较少,至少我没用过)
new出来的值由返回值的prototype而定
例如:
function
Constructor(name){
this.name
=
name
return
this.name;
}
var
person
=
new
Constructor("123");//Constructor
{name:
"123"};Object,因为基本类型的prototype都是Object
function
Constructor(name){
this.name
=
name
return
new
String(this.name);
}
var
person
=
new
Constructor("123");//String
{0:
"1",
1:
"2",
2:
"3",
length:
3,
[[PrimitiveValue]]:
"123"},
console.log(person);
运行结果:
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:测试上述代码运行效果。
更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
您可能感兴趣的文章:用方法封装javascript的new操作符(一)浅谈javascript中new操作符的原理JS重学系列之聊聊new操作符js构造函数创建对象是否加new问题JavaScript中使用构造器创建对象无需new的情况说明JavaScript
三种创建对象的方法JS
创建对象(常见的几种方法)js中创建对象的几种方式示例介绍js创建对象的几种常用方式小结(推荐)js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)javascript的函数、创建对象、封装、属性和方法、继承
(js)使用new对函数进行构造调用
js中的函数有两种调用方式,一种是通过普通的声明之后进行的调用。一种是通过new关键字进行构造调用。普通的调用就是依次执行函数内部的函数语句,如果有返回值则返回返回值,如果没有则函数内部的声明周期结束。但是,函数还有另一个调用方式,使用new关键字,将函数当做构造函数。js中没有所谓独立出来的构造函数的概念,所有的函数都用同样的方式声明,所以有了new这个关键字,js(ES6之前)只能通过这种方式实现构造器的构造。那么使用new关键字跟普通的调用有什么区别呢?
使用new关键字,比普通的函数调用,主要分为以下四个步骤:
稍后我们会对上面的四句话逐一解析,首先我们看一看函数调用的两种方式:
这样看来,两者似乎没有区别,但是这里要注意,使用new进行构造调用时,函数是有返回值的。
上面的return2并没有返回一个函数。
其实它会返回一个空的对象。这也就是上面使用new关键词的第一步, 内部创建一个新的空对象 。
那么当函数内部有this时,结果会是怎样的呢?
使用new关键字后,在函数内部如果出现了this,则自动将this指向内部新建的对象上。最后返回时,因为this的缘故,对象上新建了a属性,并且赋值返回。
修正定义的对象Object的[[prototype]]
虽然实例上的[[prototype]]属性__proto__是ES6才作为规范出版的。但是在这之前chrome已经支持__proto__属性,他指向对象的原型。
原型的问题相当复杂,单独拿出来也可以当好几篇文章的量来讲。但是这并不是本文的重点。但是每一个对象从根部来说,继承自Object。而Object.prototype上面定义了一些方法,有类似toString,valueOf等等等方法。对于对象来说,支持通过属性链和方法链向上查询。所以在一个对象实例中,如果没有定义toString方法,但它还可以向上查询,找到原型中的toString方法,进行调用。
同时的,有很多元素通过Object实现继承。比如Function, Array, RegExp等等对象,它们也是对象,但是却是继承来自Object。
在这里,内部定义的对象,让他继承来自构造函数。
最后一步,也是最容易被忽略的一步,那就是当构造函数存在返回值时,并且返回值为对象时,返回对象而不返回之前定义的对象。
当然,上面说的Function,Array,RegExp也算Object的一种,如果返回他们同样也会阻止默认的对象返回。
js中new 一个对象发生了什么?
最近在面试的时候,都会被问到在js中,new 一个实例的过程,
比如 :
定义了一个函数Person,里面有三个属性:name,age,sex;当var lisi = new Person() 的时候发生了以下4件事:
1.? var obj= {} ,创建了一个空对象 obj{}, 也就是开辟了一块内存地址,新建了一个对象实例(我是这样认为的,如果有不对的欢迎指出);
2. obj.__proto__ = Person.prototype ; 将 lisi 这个空对象的 __proto__ 指向 Person 的 prototype ,也就是设置原型链;
3. var result = Person.call(obj) ,改变this的指向,让this指向 obj 对象 ;
4。判断Person的返回值类型,如果是引用类型,则返回这个引用类型的对象,如果是普通值类型,就返回obj;
现在来看看打印出的内容:
可以看出lisi这个实例对象的构造函数是Person。