JS 核心语言基础语法 之 面向对象第二讲

举报
hwJw19 发表于 2020/12/16 17:59:58 2020/12/16
【摘要】     前面的面向对象第一讲中,我们简单的说了下面向对象的三大特征,封装和多态,都相对好理解也简单一些,而继承相对复杂一点,本文单独说一下继承的实现形式都有哪些。    1.原型链继承(b.prototype = new A();)        优点:1.简单;2.给b增加原型方法不会影响到A        缺点:1.给子类添加新方法时,必须书写在b.prototype = new A()...

    前面的面向对象第一讲中,我们简单的说了下面向对象的三大特征,封装和多态,都相对好理解也简单一些,而继承相对复杂一点,本文单独说一下继承的实现形式都有哪些。

    1.原型链继承(b.prototype = new A();)

        优点:1.简单;2.给b增加原型方法不会影响到A

        缺点:1.给子类添加新方法时,必须书写在b.prototype = new A()后面;2.无法实现多继承;3.所有的属性都是共享的;4.没有办法传递参数

    2.借用构造函数模式

        优点:1.可以实现多继承;2.解决了共享的问题;3可以传参

        缺点:1.创建的实例只是子类的实例不是父类的实例;2.只能继承构造函数中的属性和方法,不能继承原型的属性和方法;3.占用多余内存,无法复用

//示例:
function A(name){
	this.name = name
};
function B(){
	A.call(this, '张三');  //或者 A.apply(this, ['张三']);
	this.age = 29;
};
var C = new B();
alert(C.name); //张三
alert(C.age); //29

    3.组合继承(伪经典继承)

        优点:集合上面两种的优点

        缺点:父类构造函数被调用两次,存在同名覆盖的问题,并且会占用多余的内存

//示例:
function A(name){
	this.name = name;
	this.color = ['red', 'green'];
};

A.prototype.sayName = function(){
	alert(this.name);
};

function B(name, age){
	//继承属性
	A.call(this, name);
	this.age = age;
};

//继承方法
B.prototype = new A();
B.prototype.constructor = B;
B.prototype.sayAge = function(){
	alert(this.age);
};

var C1 = new B('张三', 29);
C1.color.push('black');
alert(C1.color); //'red, green, black'
C1.sayName(); //张三
C1.sayAge(); //29

    4.原型式继承

        前提:对象和对象直接的继承

        实现方式

//ES3示例:
function object(o){
  function F(){};
  F.prototype = o;
  return new F();
};

var person = {
  name: '张三',
  friends: ['李四']
};

var B = object(person);
B.name = '王五';
B.friends.push('赵六');
console.log(B); //F {name: "王五"}
console.log(person);//{name: "张三", friends: ["李四", "赵六"]}


//ES5示例:
var person = {
  name: '张三',
  friends: ['李四']
};

var B = Object.create(person);
B.name = '王五';
B.friends.push('赵六');
console.log(B); //F {name: "王五"}
console.log(person);//{name: "张三", friends: ["李四", "赵六"]}

    5.寄生式继承

//示例:
function object(o){
  function F(){};
  F.prototype = o;
  return new F();
};

function createAnother(original){
  var clone = object(original);
  clone.sayHi = function(){
    alert('Hi');
  };
  return clone;
};
var person = {
  name: '张三',
  friends: ['李四']
};

var B = createAnother(person);
B.sayHi(); //Hi

    6.寄生组合式继承(完美继承或经典继承)

        优点:解决了伪经典继承的缺点

//示例:
function inheritPrototype(B, A){
  var p = Object(A.prototype);  //var p = Object.create(A.prototype);  ES5
  p.constructor = B;
  B.prototype = p;
};

function A(name){
  this.name = name;
  this.colors = ['red', 'green']
};

A.prototype.sayName = function(){
  alert(this.name);
};

function B(name, age){
  A.call(this, name);
  this.age = age;
};

inheritPrototype(B, A);

B.prototype.sayAge = function(){
  alert(this.age);
};

var C = new B('张三',29);
C.colors.push('black');
console.log(C.colors); //["red", "green", "black"]
C.sayName(); //张三

    7.克隆

        浅克隆:原始类型按值传递,对象类型按引用传递,与原对象共用一处内存,修改会使原对象也被修改。

        深克隆:在内存中开辟一块新内存,将原对象中的所有值全部复制过去,与原对象完全脱离,修改新对象中的属性值不会影响到原对象。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。