原型和原型链

构造函数

特点:不同的是构造函数习惯上首字母大写,而构造函数需要使用new关键字来调用。

function Person(name,age,gender){
	this.name = name;
	this.age = age ;
	this.gender = gender;
	this.sayName = function(){
		console.log(name);
	}
}
var per = new Person("zhangsan",20,'女');
console.log(per); //{name: "zhangsan", age: 20, gender: "女", sayName: ƒ}
console.log(per.sayName()) //zhangsan;

每一个对象数据类型(普通的对象、实例、prototype…)也天生自带一个属性__proto__
在这里插入图片描述

原型

在javascript中,每当定义一个函数数据类型(普通函数,类),都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。

在这里插入图片描述

function person(){
	console.log("我是person")
}
console.log(person.prototype);

在这里插入图片描述
原型对象中有一个属性constructor, 它指向函数对象。

原型链

1.proto__和constructor
每一个对象数据类型(普通的对象、实例、prototype…)也天生自带一个属性__proto
,属性值是当前实例所属类的原型(prototype)。原型对象中有一个属性constructor, 它指向函数对象。

function Person(){
	console.log("我是李四");
}
var p = new Person();
console.log(p.__proto__ === Person.prototype)  //true
console.log(Person.prototype.constructor === Person) //true
//顺便学习一个ES5的方法,可以获得对象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

在这里插入图片描述
2.何为原型链
在javascript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在javaScript中式通过prototype对象,直到指向对象为止,这样就形成了一个原型链,称之原型链。

function Person(){
console.log("我是Person");
}
Person.prototype.name = "张三";
Person.prototype.sayHello = function(){
	console.log("Hello");
}
var p = new Person();
console.log(p.name)  //张三
判断是否存在a
console.log(person.hasOwnProperty('a'));//false
 console.log('a'in person)//true

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层Object为止。Object是JS中所有对象数据类型的基类(最顶层的类)在Object.prototype上没有__proto__这个属性。

console.log(Object.prototype.__proto__ === null) // true

在这里插入图片描述

实例与原型
当读取实例的属性时,如果找不到,就会查找与对象关联的原理中的属性,如果还查不到,就找原型的原型,一直找到最顶层为止。

function Person(){}
Person.prototype.name = 'Kevin';
var person = new Person();
person.name = 'Daisy';
console.log(person.name);  //Daisy
delete person.name;
console.log(person.name);  //Kevin

原型的原型

var obj = new Object();
obj.name = 'Kevin';
console.log(obj.name);

Javascript 之继承的多种实现方式和优缺点

一、 原型链继承
主要问题:

  1. 引用类型的属性被所有实例共享(this.children.push(‘name’))
  2. 在创建Child的实例的时候,不能向Parent传参
function Parent() {
      this.name = 'zhangsan';
      this.children = ['A', 'B', 'C'];
    }
    Parent.prototype.getName = function() {
      console.log(this.name);
    }
    
    function Child() {
      
    }
    Child.prototype = new Parent();
    var child = new Child();
    console.log(child.getName());

二、借用构造函数(经典继承)
优点:

  1. 避免了引用类型的属性被所有实例共享
  2. 可以直接在Child中向Parent传参
    缺点:
    方法都在构造函数中定义了,每次创建实例都会创建一遍方法
function Parent(age) {
      this.names = ['zhangsan', 'lisi'];
      this.age = age;
      
      this.getName = function() {
        return this.names;
      }
      
      this.getAge = function() {
        return this.age;
      }
    }
    
    function Child(age) {
      Parent.call(this, age);
    }
    var child = new Child(18);
    child.names.push('haha');
    console.log(child.names);
    
    var child2 = new Child(20);
    child2.names.push('yaya');
    console.log(child2.names);

三、组合继承(原型链继承和经典继承双剑合璧)
优点: 融合了原型链继承和构造函数的优点,是Javascript中最常用的继承模式

/**
    * 父类构造函数
    * @param name
    * @constructor
    */
    function Parent(name) {
      this.name = name;
      this.colors = ['red', 'green', 'blue'];
    }
    
    Parent.prototype.getName = function() {
      console.log(this.name);
    }
    
    // child
    function Child(name, age) {
      Parent.call(this, name);
      this.age = age;
    }
    
    Child.prototype = new Parent();
    // 校正child的构造函数
    Child.prototype.constructor = Child;
    
    // 创建实例
    var child1 = new Child('zhangsan', 18);
    child1.colors.push('orange');
    console.log(child1.name, child1.age, child1.colors);    // zhangsan 18 (4) ["red", "green", "blue", "orange"]
    
    var child2 = new Child('lisi', 28);
    console.log(child2.name, child2.age, child2.colors);    // lisi 28 (3) ["red", "green", "blue"]

具体的链接https://blog.csdn.net/m0_37981569/article/details/94204632

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值