JavaScript原型到原型链

Posted 江州益彤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript原型到原型链相关的知识,希望对你有一定的参考价值。

原型(显示原型和隐式原型)

每一个javascript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

核心:实例对象的隐式原型的值为其对应构造函数的显式原型的值

function Fun(){
//内部自动执行语句:this.prototype={};
}

显式原型prototype

1.每个函数function都有一 个prototype, 定义函数时自动添加,显式原型prototype是一个对象,且默认指向一个空的Object对象

console.log(Fun.prototype);

2.原型对象中有一个属性constructor,它指向函数对象

console.log(Fun.prototype.constructor===Fun);//true

3.给原型对象添加属性,一般是添加方法。给其实例对象使用

function Fun(){
//内部自动执行语句:this.prototype={};
}

Fun.prototype.test=function(){
	console.log("给函数的原型对象添加属性,给其实例对象使用");
}

var fun =new Fun();//函数也是对象
fun.test();//给函数的原型对象给原型对象添加属性,给其实例对象使用

每个实例对象(除了 null )都有隐式原型__proto__

每个实例对象(除了 null )都有一个__proto__属性, 称为隐式原型,这个属性会指向该对象的原型

function Fun(){
	//内部自动执行语句:this.prototype={};
}
let obj = new Fun();//内部自动执行语句:this.__proto__=Fun.prototype;
console.log(obj .__proto__);

实例对象的隐式原型的值,为其对应构造函数的显式原型的值

function Fun(){
	//内部自动执行语句:this.prototype={};
}
let obj = new Fun();//内部自动执行语句:this.__proto__=Fun.prototype;
console.log(obj.__proto__ == Fun.prototype);//true
function Fun(){
	//内部自动执行语句:this.prototype={};
}

Fun.prototype.test=function(){
	console.log("在函数的显示原型属性中添加方法");
}
let obj = new Fun();//内部自动执行语句:this.__proto__=Fun.prototype;
obj.test()//使用隐式原型调用显示原型定义的方法

总结:

实例看隐式原型
函数看显示原型

function Fun(){
	//内部自动执行语句:this.prototype={};
}
Fun.prototype.test=function(){
	console.log("在函数的显示原型属性中添加方法");
}

let obj = new Fun();//内部自动执行语句:this.__proto__=Fun.prototype;
obj.test()//使用隐式原型调用显示原型定义的方法

在这里插入图片描述

原型链

在这里插入图片描述

原型链使用来查找属性的值
在这里插入图片描述
1.读取对象的属性值时: 会自动到原型链中查找
2.设置对象的属性值时不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
3.方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

function Fn() {}

Fn.prototype.a ='AAA';
var fn1=new Fn();
console.log(fn1.a);//AAA

var fn2 = new Fn();
fn2.a = 'BBB';//设置对象的属性值时不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
console.log(fn1.a, fn2.a)//AAA , BBB

方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

function Person(name, age) {
	this.name = name;//属性添加在构造函数上
	this.age = age;//属性添加在构造函数上
}
Person.prototype.setName = function(name) {//方法添加在原型上,因为每一个实例对象的方法可能不同
	this.name = name;
}
var p1 = new Person('Tom', 12) ;
p1.setName('Bob');
console.log(p1);

在这里插入图片描述

原型中常用的方法

hasOwnProperty

instanceof

  1. instanceof是如何判断的?
  • 表达式: A instanceof B
  • 如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false
  1. Function是通过new自己产生的实例
    如下:
    Object是Function的实例
    Function是Function自己的实例
console.log(Object instanceof Function);
console.log(Object instanceof Object);
console.log(Function instanceof Function);
console.log(Function instanceof Object);

function Foo() {}
console.log(Object instanceof Foo);



面试题

面试题1

function Fn() {}
function Fn2() {}
Fn.prototype = new Fn2();
Fn2.prototype = new Fn();//删除线格式 
const fn = new Fn();
const fn2 = new Fn2();
console.log(fn.constructor, fn2.constructor);//constructor 属性返回对创建此对象的数组函数的引用。

FN的原型是Fn2
调用构造就是Fn2
Fn给Fn2赋值,此时Fn的原型就是Fn2,所以fn2相当于没有变化
说明:下图有一处错误,地址0x003对应的因该是Fn2:0x003
在这里插入图片描述

面试题2

const A = function() {this.value = 1;}
const B = function() {this.value = 2;}
const C = function() {this.value = 3;}
const c = new C();
A.prototype = new B();
C.prototype = new A();
console.log(c.__proto__.value, c.__proto__.constructor);

在这里插入图片描述

面试题3

function F() {};
Object.prototype.a = function() {
	console.log('a()');
}
Function.prototype.b = function() {
	console.log('b()');
}

var f = new F();

f.a();//a()
f.b();//f.b is not a function
F.a();//f.a is not a function
F.b();//b()

综合题

function Foo() {
	getName = function() {
		console.log(1);
	};
	return this;
}
Foo.getName = function() {
	console.log(2);
};
Foo.prototype.getName = function() {
	console.log(3);
};
var getName = function() {
	console.log(4);
};

function getName() {
	console.log(5);
}

//请写出下列的输出结果
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//new(Foo.getName)()-->new(function() {console.log(2);})()-->2
new Foo().getName();//(new Foo()).getName()-->foo.getName()-->function() {console.log(3);}-->3)
new new Foo().getName();//new (foo.getName)()-->new(function() {console.log(3);})-->3

最后推荐一篇好文章《[JavaScript深入之从原型到原型链 #2](https://github.com/mqyqingfeng/Blog/issues/2)》

以上是关于JavaScript原型到原型链的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中原型以及原型链

JavaScript之粗浅原型和原型链

图说原型链

JavaScript 原型继承原型链

JavaScript对象原型链继承闭包

JavaScript 深入之从原型到原型链(转载)