var myArr = Object();
myArr.name = "javascript";
myArr.age = 2017;
console.log(myArr);//Object {name: "javascript", age: 2017}
console.log(typeof myArr);//object
console.log(myArr.name);//javascript
function Fun(){}
var a = new Fun();
a.name = "javascript";//去掉new后,Cannot set property 'name' of undefined
a.age = 2017;//去掉new后,Cannot set property 'age' of undefined
console.log(a);//Fun {name: "javascript", age: 2017}
console.log(typeof a);//object
console.log(a.name);//javascript
上面代码中,使用“内置对象Object”创建对象,可以不使用new,Array也可以不使用new。
但是使用构造函数创建对象的话,如果不使用new就只是一个函数的返回值,也无法创建属性。
在我的理解,他们都是对象,为什么创建的时候就有区别了呢?
这是不是因为“Object”本来就是对象,而构造函数是通过函数封装的对象的原因呢?
我也不知道为什么我会有好多千奇百怪的问题。。。
ringa_lee2017-04-11 12:40:58
Object 里面有判断有没有写 new 的代码。如果没写就返回 return new Object()
。在你的 Fun
里面也可以添加。比如:
也可以
function _Fun_() {}
function Fun(){
// 这样 new Fun() 和 Fun() 就没有区别了。
return new _Fun_();
}
详见
http://zonxin.github.io/post/...
天蓬老师2017-04-11 12:40:58
不是很理解你的问题。。我说几点,希望对你有帮助~
Object
和Fun
一样是一个函数,他们本质上是Object
类型的
直接调用 a = Fun()
,称之为一般函数调用,而你的Func
函数体内没有返回结果,所以a=undefined
,当然你不能给一个undefined
创建属性。
通过a = new Fun()
调用,称之为构造函数调用。当通过new
调用一个函数时发生了这几件事。
以a = new Fun()
为例
构造一个空对象,假设命名为 obj = {}
,绑定obj
的__prot__
到Fun.prototype
(涉及到js的原型链继承)
绑定函数执行环境中的this
到刚才创建的空对象(即obj
)上 (希望你理解了js中的this
...)
执行Func
函数体
如果函数体返回值是undefined
、null
或者不是Object
类型,则返回值为最开始的obj
所以var a = new Fun()
,a
的值为空对象{}
。
a.name = "javascript";
会直接在a
上添加属性name="javascript"
(这句话深究起来其实不简单..,懒得展开了,题主有兴趣多看书把。)
使用“内置对象Object”创建对象,可以不使用new,Array也可以不使用new。
最后Object
,Array
可不使用new
,因为他们内部做了判断,如果不是构造函数调用自动添加new
.
巴扎黑2017-04-11 12:40:58
是都可以创建对象,但是new 方法创建的对象的原型是 Fun ,即a.__proto__ = Fun.protoType;而第一种是myArr.__proto__ = Object.protoType
看了一下题,发现回答有所偏差,其实可以在Fun中添加以下代码,实现安全的构造函数,达到不使用new也可创建函数:
function Fun(){
if(!this instanceof Fun){
return new Fun();
}
}
ringa_lee2017-04-11 12:40:58
var a=Fun()表示a为函数Fun()的返回值,你Fun(){}没有返回值,a就是undefined
你试试var a = Fun(){return new Object()}呗
ringa_lee2017-04-11 12:40:58
我怎么记得,不用new的,那是工厂模式。
说白了就是以这个函数的返回值作为新的对象,如果你想这个函数加不加new
都一样构造新的对象的话,那不想作为构造函数的其他函数怎么用呢。
function add(a,b){
this.sombra='boo';
return a+b;
}
var c=add(1,2);//3
var d= new add();//{sombra:'boo'}
伊谢尔伦2017-04-11 12:40:58
其实你要是把:
var myArr = Object();
换成
var myArr = new Object();
你不会觉得这么奇怪了,二者是相等的,只不过当你不以构造函数形式调用 Object
时,Object
等同于 new Object()
。(注:Array也是一样)
但这样讲反而会更迷惑,为什么呢?原因在于原型树。可这样的话,头这一定会更头大;要不就说一说为什么需要 new
?
我用你的示例进行思维拓展,假设你是在创建一个用户对象:
var myArr = Object();
myArr.name = "javascript";
myArr.age = 2017;
一个实例代表着一个人的姓名和年龄;我在这个基础增加了一个动作,即:zodiac()
方法来计算生肖。
那好,假如我现在需要10个用户信息,那么我需要这样:
var users = [];
for (var i = 0; i < 10; i++) {
var myArr = new Object();
myArr.name = "javascript";
myArr.age = 2017;
myArr.zodiac = function() { return this.age === 1 ? '属龙' : '属鼠'; }
users.push(myArr);
}
看似很简单,但首先每个实例都带有 zodiac()
方法是不是太浪费内存了?每一个计算生肖的是依赖时年龄,也没有必要每一次都创建。
那好,我们可以改进一下,来解决这两个疑问。
function User() { }
// 用户生肖
function UserZodiac() {
this.zodiac = function() {
return this.age === 1 ? '属龙' : '属鼠';
}
}
// 将用户的原型绑定到用户生肖
var userZodiac = new UserZodiac();
User.prototype = userZodiac;
var users = [];
for (var i = 0; i < 10; i++) {
var myArr = new User();
myArr.name = "javascript";
myArr.age = 2017;
users.push(myArr);
}
当我们创建10个用户时,只需要实例一次 UserZodiac
。
这才是 new
的魅力。
其实当你调用一个函数时,new
不 new
没有什么区别,更有一些人提倡放弃 this
(相当于放弃new)。
老是有人拿原型树来考核一个人是否真懂JavaScript其实挺不合理。