Javascript原型及原型链

在 Javascript 中原型和原型链是比较神奇也是比较让人难以理解的知识点,但是一旦弄懂了这部分的知识,也就正式迈入了进阶的门槛了。现在我就大概的把我所理解的写一下。等以后理解深入了,再修稿。

一、对象

在 Javascript 中,万物皆可对象,但是不同的对象也是分三六九等的。首先,Object 是顶级公民,从名字上看也懂,这是JS的’亲儿子’,一等公民就是 Function。其他剩下的 String,Array,Date,Number,Boolean,Math等内建对象都是’臭鱼烂虾’。但是大概的分类就是普通对象函数对象

var o1 = {}; 
var o2 =new Object();
var o3 = new f1();

function f1(){}; 
var f2 = function(){};
var f3 = new Function('str','console.log(str)');

console.log(typeof Object); //function 
console.log(typeof Function); //function  

console.log(typeof f1); //function 
console.log(typeof f2); //function 
console.log(typeof f3); //function   

console.log(typeof o1); //object 
console.log(typeof o2); //object 
console.log(typeof o3); //object

其实俩个分类的区分还是很简单的,只要通过 New Function() 的方式创建的都是函数对象。

二、构造函数

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() { alert(this.name) } 
}
var p1 = new Person('Zaxlct', 28, 'Software Engineer');
var p2 = new Person('Mick', 23, 'Doctor');

这个例子里面,P1和P2都是 Person 的实例,这两个实例都有一个 constructor(构造函数)属性,该属性(是一个指针)指向 Person。

console.log(p1.constructor == Person); //true
console.log(p2.constructor == Person); //true

在 Chrome 的命令行中就能打印中其他的关系(是有联系的),总结一句话就是:实例的构造函数属性(constructor)指向构造函数

三、原型

在 JavaScript 中,每当定义一个对象的时候,对象中都会包含一些预定义的属性。其中每个对象肯定都包含有一个 prototype 属性 ( prototype 本身也是对象 ),这个属性指向函数的原型对象。

function Person() {}
Person.prototype.name = 'nys';
Person.prototype.age  = 28;
Person.prototype.job  = 'Software Engineer';
Person.prototype.sayName = function() {
  alert(this.name);
}
  
var person1 = new Person();
person1.sayName(); // 'nys'

var person2 = new Person();
person2.sayName(); // 'nys'

这个例子就是使用原型模式构建了原型对象,其实原型对象就是 Person.prototype 。当然,上面的构造方面也有简写模式:

Person.prototype={
   name: 'nys',
   age: 80,
   job: 'Software Engineer',
   sayName: function(){
       alert(this.name)
   }

在上面的例子中,定义了 name , age , job , sayName() 四个属性,但是不能忽略他的默认属性:constructor,但是它是干嘛的呢?大概就是这样:

Person.prototype.constructor == Person

记住一点:constructor 这个玩意儿是个指针,指向 Person

总结:

Person           构造函数
Person.prototype 原型对象
constructor      属性(原型对象和实例都会拥有),指向构造函数

p1 为什么有 constructor 属性?那是因为 p1 是 Person 的实例。
Person.prototype 为什么有 constructor 属性?同理, Person.prototype (你把它想象成 A) 也是Person 的实例。
也就是在 Person 创建的时候,创建了一个它的实例对象并赋值给它的 prototype。

四、proto

JS 在创建对象的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。对象 p1 有一个 __proto__ 属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:

person1._proto_== Person.prototype

//大概就是这样的关系
Person.prototype.constructor == Person;
person1.__proto__ == Person.prototype;
person1.constructor == Person;

五、原型链

5.1 什么是原型链?

原型链的核心就是依赖对象的 _proto_ 的指向,当自身不存在的属性时,就一层层的扒出创建对象的构造函数,直至到Object时,就没有 _proto_ 指向了。

5.2 如何分析原型链?

因为 _proto_ 实质找的是 prototype ,所以我们只要找这个链条上的构造函数的 prototype 。其中 Object.prototype 是没有 _proto_ 属性的,它==null。

5.3 最简单的原型链分析

function Person(name){
    this.name = name;
}
var p = new Person();
//p ---> Person.prototype --->Object.prototype---->null

5.4 属性搜索原则:

  1. 当访问一个对象的成员的时候,会现在自身找有没有,如果找到直接使用。
  2. 如果没有找到,则去原型链指向的对象的构造函数的prototype中找,找到直接使用,没找到就返回undifined或报错。

5.5 原型继承

//原型继承的基本案例
function Person(name, age) {
	this.name = name;
	this.age = age;
}
//1.直接替换原型对象 
var parent = {
	sayHello : function() {
		console.log("方式1:替换原型对象");
	}
}
Person.prototype = parent;
var p = new Person("张三", 50);
p.sayHello();
//2.混入式原型继承
console.log(".............混入式原型继承..............");
function Student(name, age) {
	this.name = name;
	this.age = age;
}
var parent2 = {
	sayHello : function() {
		console.log("方式2:原型继承之混入式加载成员");
	}
}
for ( var k in parent2) {
	Student.prototype[k] = parent2[k];
}
var p = new Student("张三", 50);
p.sayHello();

原型链参考->

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值