适逢传说中的金三银四,最近在阅读掘金和GitHub的时候看多多次各路大牛出的关于原型链的题目,如果没有深刻的理解,过一段时间就会又不知所云。
我也是在做过此类题目一段时间后又模糊了其含义。因此特意在笔记本上画了原型对象与原型链的示意图来帮助理解。提到这,我个人还是比较喜欢使用纸质笔记本记录知识,平时看到一个小的知识点就可以随手记录下来。
本文涉及点:
- 1.面向对象三大特性
- 2.继承
- 3.构造函数
- 4.原型链
- 5.认识和创建对象的几种方法
- 6.new运算符
- 7.instanceof及其原理
1.面相对象的三大特性
- 封装
- 继承
- 多态
2.当谈到继承时,JavaScript 只有一种结构:对象。
每个实例对象(object )都有一个私有属性(称之为__proto__)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象(proto) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
3.原型链
几乎所有 JavaScript 中的对象都是位于原型链顶端的Object的实例。
原型链的基本原理:任何一个实例,通过原型链,找到它上面的原型,该原型对象中的方法和属性,可以被所有的原型实例共享。
这里先说下构造函数:
1、构造函数通过 new 生成实例
2、构造函数也是函数,构造函数的prototype指向原型。(所有的函数有prototype属性,但实例没有 prototype属性)
3、原型对象中有 constructor,指向该原型的构造函数。
如下图:
这样梳理一遍可以加深理解。
4.认识与创建对象的几种方法
在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:
普通对象 Object 和 函数对象 Function。
一般而言,通过 new Function 产生的对象是函数对象,其他对象都是普通对象。
1.创建函数
如下代码:
//函数声明
function f1() {
console.log("函数的声明")
}
//函数表达式
var f2 = function () {
console.log("f2实际上是一个匿名函数,把这个匿名函数赋值给了f2")
};
//直接new Function() 创建函数
var f3 = new Function('x', 'console.log(x)');
console.log(
typeof f1,//function
typeof f2,//function
typeof f3//function
);
2.创建对象 的方法
创建对象代码:
var o1 = {};//字面量
var o2 = new Object();//使用new表达式
var o3 = new f1();
console.log(
typeof o1,//object
typeof o2,//object
typeof o3//object
);
-
方式一:对象字面量
var obj1 = {name: 'xiaohua'};//字面量的方式 var obj2 = new Object(name: `xiaohua`); //内置对象(内置的构造函数)的方式
上面的两种写法,效果是一样的。因为,第一种写法,obj1会指向Object。
-
方式二:通过构造函数,使用new表达式
var f1= function (name) { this.name = name; } var obj3 = new f1('xiaohua');
-
方式三:Object.create
Object.create方法创建的对象,是用原型链连接的。var f2 = {name:'xiaohua'}; var obj3 = Object.create(f2);
这种方法很少有人可以说出来,这里obj3是实例,f2是obj3的原型,name是f2原型里的属性。构造函数是Objecet 。
5.new运算符
当new一个实例new f1(‘xiaohua’)的时候,发生了什么?
(1)创建一个新的空对象实例。
(2)将此空对象的隐式原型指向其构造函数的显示原型。
(3)执行构造函数(传入相应的参数,如果没有参数就不用传),同时 this 指向这个新实例。
(4)如果返回值是一个新对象,那么直接返回该对象;如果无返回值或者返回一个非对象值,那么就将步骤(1)创建的对象返回。
6.instanceof
1.定义
instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置。
(来自MDN)
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
(来自MDN)
instanceof的作用:用于判断实例属于哪个构造函数。
instanceof的原理:判断实例对象的__proto__属性,和构造函数的prototype属性,是否为同一个引用(是否指向同一个地址)。
2.语法
object instanceof constructor
参数:
object:要检测的对象。
constructor:某个构造函数。
特别说明:
注意1:虽然说,实例是由构造函数 new 出来的,但是实例的__proto__属性引用的是构造函数的prototype。也就是说,实例的__proto__属性与构造函数本身无关。
注意2:在原型链上,原型的上面可能还会有原型,以此类推往上走,继续找__proto__属性。这条链上如果能找到, instanceof 的返回结果也是 true。
【每天学习一个点,慢慢的,慢慢的,慢慢的!】