1.在非严格模式下,传入参数,实参和arguments的值会共享,当没有传入的时候,实参与arguments值不会共享。
在严格模式下,实参和arguments不会共享
//非严格模式
function f(a,b,c){
console.log(a,arguments[0])// 1,1
console.log(c,arguments[2])// undefined,undefined
a=2;
c=2;
console.log(a,arguments[0])//2,2
console.log(c,arguments[2])//2,undefined
}
f(1,1)
//严格模式
function f(a,b,c){
'use strict'
console.log(a,arguments[0])// 1,1
console.log(c,arguments[2])// undefined,undefined
a=2;
c=2;
console.log(a,arguments[0])//2,1
console.log(c,arguments[2])//2,undefined
}
f(1,1)
2.使用动态原型模式时,不能使用对象字面量重写原型
function Person(name){
this.name=name;
if(typeof this.getName!='function'){
Person.prototype={
constructor:Person,
getName:function(){
console.log(this.name)
}
}
}
}
var person1=new Person('Sally');
var person2=new Person('Vincent');
person1.getName();//报错没有该方法
person2.getName();//注释掉上面的代码,这句诗可以执行的。
原因在于使用new实例化一个对象的时候,实际上进行了如下的操作:
var obj=new object();
obj.__proto__=Person.prototype;
var result=Person.apply(obj,..args)
return typeof result=='object'?result:obj;
也就是说是先创建一个空对象;
再将对象的__proto__指向构造函数的原型对象;
在这一步对象的__proto__已经指向一个原型对象了,我们这里设为原型A,
之后才开始执行apply,在其上调用构造函数,构造函数执行到if语句时候,因为一开始是不存在方法,所以就会执行对象字面量改变Person的prototype,这里等于给Person的prototype重新赋值,这里的原型为B,所以创建出来的person1的__proto__指向原型A,而方法是挂载在原型B上的,最终导致方法不存在,而person2调用的方法是可以用的。
如果想要使用对象字面量的话,可以在if语句中返回一个新的对象,如下:
function Person(name){
this.name=name;
if(typeof this.getName!='function'){
Person.prototype={
constructor:Person,
getName:function(){
console.log(this.name)
}
}
return new Person(name);
}
}