构造函数与各种继承方法特点

---使用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();
}
时间: 2024-10-08 18:47:28

构造函数与各种继承方法特点的相关文章

MDN——javascript——入门——第三章对象——对象.构造函数.原型链.继承——知识点总结

对象Object 由属性property(变量).方法method(函数)组成 var objectName = { member1Name : member1Value, member2Name : member2Value, member3Name : member3Value } member(成员)的值是任意的, 一个如上所示的对象被称之为对象的字面量(literal)——手动的写出对象的内容来创建一个对象.不同于从类实例化一个对象,我们会在后面学习这种方式. 访问对象成员 1.点表示法

JS原型链与几种继承方法的对比

继承的方式有两种:接口继承.实现继承接口继承:即虚函数,父类只定义接口,不具体实现子类继承接口,自己负责实现这个方法,运行时动态决定调用哪个实现.实现继承:父类实现的方法,子类可以直接调用 JS中只支持实现继承,以原型链来实现. 回顾一下构造函数.原型.实例的关系:每个构造函数都有一个原型对象,原型对象又都包含一个constructor指针指向构造函数,实例包含一个_proto_内部属性指向原型对象. 继承的实现方法(父类型叫Parent,子类型叫Child)原本Child.prototype

javascript的继承方法

一.构造函数继承 该方法最简单,使用call或者apply方法,将父对象的构造函数绑定到子对象上. function Parent(name){ this.name = name; this.color = ['red','green']; this.getInfo = function(){ alert(this.name + '喜欢的颜色:'+ this.color) } } function Child(name){ Parent.call(this,name); } var child1

5种JS继承方法

<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.jb51.net/" /> <title>5种JS继承方法</title> <script type="text/javascript"> //1

避免在构造函数中调用虚方法(Do not call overridable methods in constructors)

CLR中说道,不要在构造函数中调用虚方法,原因是假如被实例化的类型重写了虚方法,就会执行派生类型对虚方法的实现.但在这个时候,尚未完成对继承层次结构中所有字段的初始化.所以,调用虚方法会导致不可预测的行为.归根结底,这是由于调虚方法时,直到运行时之前,都不会选择执行该方法的实际类型. 在MSDN中,也给我我们详细的提示和范例. https://msdn.microsoft.com/en-us/library/ms182331.aspx 那我们就亲手来测试一下,新建两个类,Perople类,Chi

Date类型之继承方法

ECMAScript中的Date类型是在早期Java中的java.util.Date类型基础上构建的.为此,Date类型使用自UTC(国际协调时间)1970年1月1日午夜零时开始经过的毫秒数来保存日期.可以使用new操作符和Date构造函数创建日期对象,在使用Date构造函数而不传递参数的情况下,新创建的对象自动获取当前的时间日期.如果想要根据特定的日期和时间创建日期对象,就必须传入表示该日期的毫秒数(从UTC时间1970年1月1日午夜零时起至该日期止经过的毫秒数),为了简化计算过程,ECMAS

对象冒充实现继承,原型链继承方法,以及组合继承模式

function Person (){ this.name=“张三”; this.run = function(){ alert( this.name+'在运动' ) } } Person.prototype.work = function(){ alert( this.name+'在工作’ ) } // web类 继承person类 原型链+对象冒充的组合继承模式 function web(){ Person.call( this )  //  对象冒充实现继承 } var w = new w

Js的继承方法

Js继承 要想继承,就必选有一个要被继承的产业 function who(name){ this.name = name this.say = function(){ console.log(this.name) } } who.prototype.age = 10 第一种方法:原型链继承 function xiaoming(){ this.name = 'xiaoming' } xiaoming.prototype = new who() let xiaoming1 = new xiaomin

第三篇 -- 界面与逻辑分离的设计方法(多继承方法和单继承方法)

一.多继承方法 1. 画图Form.ui,生成Form.py UI: Form.py # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'Form.ui' # # Created by: PyQt5 UI code generator 5.13.0 # # WARNING! All changes made in this file will be lost! from PyQt5 impor