您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

js的2种继承方式详解_javascript技巧

2024/3/2 11:34:12发布10次查看
js中继承可以分为两种:对象冒充和原型链方式
一、对象冒充包括三种:临时属性方式、call()及apply()方式
1.临时属性方式
复制代码 代码如下:
function person(name){
     this.name = name;
     this.say = function(){
          alert('my name is '+this.name);
     }
}
function f2e(name,id){
     this.temp = person;
     this.temp(name);
     delete this.temp;
     this.id = id;
     this.showid = function(){
          alert('good morning,sir,my work number is '+this.id);
     }
}
var simon = new f2e('simon',9527);
simon.say();
simon.showid();
2.call()/apply()方式
实质上是改变了this指针的指向
复制代码 代码如下:
function person(name){
     this.name = name;
     this.say = function(){
          alert('my name is '+this.name);
     }
}
function f2e(name,id){
     person.call(this,name); //apply()方式改成person.apply(this,new array(name));
     this.id = id;
     this.showid = function(){
          alert('good morning,sir,my work number is '+this.id);
     }
}
var simon = new f2e('simon',9527);
simon.say();
simon.showid();
缺点:先来看这么一张内存分配图:
在oo概念中,new实例化后,对象就在堆内存中形成了自己的空间,值得注意的是,这个代码段。而成员方法就是存在这个代码段的,并且方法是共用的。问题就在这里,通过对象冒充方式继承时,所有的成员方法都是指向this的,也就是说new之后,每个实例将都会拥有这个成员方法,并不是共用的,这就造成了大量的内存浪费。并且通过对象冒充的方式,无法继承通过prototype方式定义的变量和方法,如以下代码将会出错:
复制代码 代码如下:
function person(name){
     this.name = name;
     this.say = function(){
          alert('my name is '+this.name);
     }
}
person.prototype.age = 20;
person.prototype.sayage = function(){alert('my age is '+this.age)};
function f2e(name,id){
     person.apply(this,new array(name));
     this.id = id;
     this.showid = function(){
          alert('good morning,sir,my work number is '+this.id);
     }
}
var simon = new f2e('simon',9527);
simon.sayage(); //提示typeerror: simon.sayage is not a function
二、原型链方式
复制代码 代码如下:
function person(){
     this.name = 'simon';
}
person.prototype.say = function(){
     alert('my name is '+this.name);
}
function f2e(id){
     this.id = id;
     this.showid = function(){
          alert('good morning,sir,my work number is '+this.id);
     }
}
f2e.prototype = new person();
var simon = new f2e(9527);
simon.say();
simon.showid();
alert(simon.hasownproperty('id')); //检查是否为自身属性
接下来按照上面的例子来理解以下js原型链概念:
原型链可以理解成:js中每个对象均有一个隐藏的__proto__属性,一个实例化对象的__proto__属性指向其类的prototype方法,而这个prototype方法又可以被赋值成另一个实例化对象,这个对象的__proto__又需要指向其类,由此形成一条链,也就是前面代码中的
复制代码 代码如下:
f2e.prototype = new person()
这句是关键。js对象在读取某个属性时,会先查找自身属性,没有则再去依次查找原型链上对象的属性。也就是说原型链的方法是可以共用的,这样就解决了对象冒充浪费内存的缺点。
下面再来说缺点:
缺点显而易见,原型链方式继承,就是实例化子类时不能将参数传给父类,也就是为什么这个例子中function person()没有参数,而是直接写成了this.name=”simon”的原因。下面的代码将不能达到预期的效果:
复制代码 代码如下:
function person(name){
     this.name = name;
}
person.prototype.say = function(){
     alert('my name is '+this.name);
}
function f2e(name,id){
     this.id = id;
     this.showid = function(){
          alert('good morning,sir,my work number is '+this.id);
     }
}
f2e.prototype = new person();
var simon = new f2e(simon,9527);
simon.say();
simon.showid();
function person(name){
     this.name = name;
}
person.prototype.say = function(){
     alert('my name is '+this.name);
}
function f2e(name,id){
     this.id = id;
     this.showid = function(){
          alert('good morning,sir,my work number is '+this.id);
     }
}
f2e.prototype = new person();  //此处无法进行传值,this.name或者name都不行,直接写f2e.prototype = new person('wood')是可以的,但是这样的话simon.say()就变成了my name is wood
var simon = new f2e(simon,9527);
simon.say();  //弹出 my name is undefined
simon.showid();
最后,总结一下自认为较好的继承实现方式,成员变量采用对象冒充方式,成员方法采用原型链方式,代码如下:
复制代码 代码如下:
function person(name){
     this.name = name;
}
person.prototype.say = function(){
     alert('my name is '+this.name);
}
function f2e(name,id){
     person.call(this,name);
     this.id = id;
}
f2e.prototype = new person();
//此处注意一个细节,showid不能写在f2e.prototype = new person();前面
f2e.prototype.showid = function(){
     alert('good morning,sir,my work number is '+this.id);
}
var simon = new f2e(simon,9527);
simon.say();
simon.showid();
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product