---使用new运算符调用一个函数时,总是返回一个对象
1、当使用new调用任何函数时,它会发生如下事情:
2、后台自动创建一个“空”对象,通过this引用该对象;var this={};//伪代码
3、可任意给this添加属性
4、在函数的末尾隐式返回this
但也可以通过下面的步骤返回不同的不同对象:
function Dog(){ var oDog=new Dog();
var noThis={noname:"Any"}; oDog.name; //undefined
this.name="Fod"; oDog.noname.name;//Any 返回定制的对象(不是this)
return noThis;//覆盖了
}
当使用new的时候,可以返回一个定制的对象(不是this),如果返回一个非对象(标量值),将会导致返回值被忽略,最终仍会得到this。例如:
function Dog(){ var oDog=new Dog();
this.name="Fod"; oDog.name; //Fod
return 1;
}
当引用一个构造函数的时候,可能会忘记加上new 我们可以通过这个函数以构造函数的方式返回
function Dog(){
if(!(this instance Dog)){
return new Dog();
}
}
----//直接字面量继承另外一个直接字面量的属性
function extend(parent){
var child={};
for(var name in paret){
if(parent.hasOwnProperty(naem)){
child[name]=parent[name];
}
}
return child;
}
//临时构造函数
function extend(obj){
var F=function(){};
F.prototype=o;
return new F();
}
function extend(parents,child){
var F=function(){};
F.prototype=parent.prototype;
child.prototype=new F();
child.prototype.constructor=child;
}
每个对象都连接到一个原型对象,并且可以从中继承属性,所以通过对象字面量创建的对象都连接到Object.prototype----JS标配对象
----借用构造函数的时候,新对象会得到父对象中的tags成员:
function Parent(){
this.name=["CSS","JS"];
}
Parent.prototype.sayName=function(){console.log(this.name)};
var oParent=new Parent();
function Child1(){};
child.prototype=oParent;
var oChild1=new Child1();
oChild1.sayName();
function Child2(){ //不能继承原型上的属性或方法
Parent.call(this);
}
var oChild2=new Child2();
oChild2.sayName(); //Uncaught TypeError: oChild2.sayName is not a function(…)
console.log(oChild1.hasOwnProperty("name")); //false
console.log(oChild2.hasOwnProperty("name")); //true
oChild1.name.push("php");
oChild2.name.push("Java"); //只是一个副本,不能往上级的属性中添加值
console.log(oParent.name); //["CSS","JS","php"]
------借用和设置原型,父对象的本身属性和原型属性都能得到
function Child(){
Parent.apply(this,arguments);
}
Child.prototype=new Parent();
var oChild=new Child();
oChild.sayName();
面向对象:
var obj={};
Object.defineProperty(obj,"name",{
writable:false|true,//是否可更改
ennumerable:false|true,//是否可枚举
configurable:false|true,//是否可删除
value:"" //设置值
});
定义多个属性:
Object.defineProperties();
Object.create();//传入的第一个参数为创建的对象的原型对象
isPrototypeOf();Person.isPrototypeOf(person1);//true|false
Object.getPrototypeOf()获取某实例的原型 //Object.getPrototypeOf(person1);Person.prototype
hasOwnPrototype()//检测一个属性是否存在于实例,该方法是从Object继承而来的
in 操作符
Object.keys()接受一个对象为参数,返回一个字符串数组——包含了所有的可枚举的属性、
Object.getOwnPropertyNames()//可枚举或不可的都被返回
prototype的重写以及解决方法
继承:
实现继承主要是依靠原型链,实现本质就是重写属性原型。
存在于被继承的对象实例中所有属性方法,也存在与主动继承的原型中,因为主动继承对象的原型为被继承对象的实例
Sub的实例constructor属性指向Sup对象,这是因为主动继承对象原型被重写的缘故——>Sub的原型指向Sup的原型,而Sub的原型的constructor属性指向的是Sup。
借用构造函数://只能继承实例中的属性和方法
function Child(name){ Parent.call(this,name); }
组合继承://会将超类的实例属性继承两次,第一次集成到实例中,第二次继承到原型中,原型中的被覆盖,因此有了后面的组合寄生式继承
function Child(name){ Parent.call(this,name); } Child.prototype=new Parent();
原型式继承:
function object(o){ var F=function(){}; F.prototype=o; return new F(); }
寄生式继承:
function createAnother(origin){ var F=function(){}; F.prototype=o; var clone=new F(); clone.addfn=function(){};//被添加的函数不能复用,效率较低。 }
寄生式组合继承:
var Sub=function(){ Sup.call(this); } function extend(Child,parent){ var F=function(){}; F.prototype=Parent.prototype; Child.prototype=new F(); }