面向对象:面向对象、原型对原型、原型链、Function、Object 的理解什么是 JS 原型链?转载以上文章
一、OOP(Object-oriented programming, 面向对象编程)
1、wiki 的解释
面向对象编程 (OOP) 是一种基于“对象”概念的编程范式。该对象包含数据(属性),以及一些执行过程的代码(即方法)。对象的一个特性是,调用对象的方法过程可以访问并经常修改与其关联的对象的数据字段(对象具有“this”或“self”的概念)。
2、面向对象的思路:
把某个功能看成一个整体(对象),通过调用对象的某个方法来启动功能。在用的时候不去考虑这个对象内部的实现细节,在去实现这个对象细节的时候不用管谁在调用
3、例子
面向对象的写法
Car. 拧钥匙()
Car. 挂挡()
Car. 踩油门()
二、构造对象
1、代码
通过 new 函数名 (‘ 参数,参数 ’) 得到一个对象,就相当于这个对象就是这个函数构造出来的,这个对象是函数的实例
function Person(name) {
this.name = name
this.sayName = function() {
console.log(this.name)
}
}
var p = new Person(‘hunger’)
2、instanceof
instanceof 是一个操作符,可以判断对象是否为某个函数的实例
p1 instanceof Person; // true
p1 instanceof Object;// true
instanceof 判断的是对象,非对象的数据不能判断
1 instanceof Number; // false
3、构造函数的过程
创建一个空对象 {},假设名字是 tmpObj,并空对象的__proto__特性指向函数的 prototype 属性
执行 Person 函数,执行过程中对 this 操作就是对 tmpObj 进行操作
函数执行完后返回刚刚创建的 tmpObj
把 tmpObj 赋值给 p (p 也指向同一个对象)
4、构造函数的原型链
1、对函数使用 new 表达式就是构造函数
2、每个函数都有名称为 prototype 属性,叫做原型,是一个对象
3、每个对象都有一个内部属性 _proto_(规范中没有指定这个名称,但是浏览器都这么实现的) 指向其类型的 prototype 属性,类的实例也是对象,其__proto__属性指向“类”的 prototype
4、所有实例(对象)都会通过原型链引用到类型(函数)的 prototype(原型),prototype 相当于特定类型所有实例都可以访问到的一个公共容器,一般用来共同调用的函数
总结:
我们通过函数定义了类 Person,类(函数)自动获得属性 prototype 每个类的实例都会有一个内部属性__proto__,指向类的 prototype 属性
5、举个栗子
默认情况下,我们写构造函数是不需要 return 的,构造函数自动将 this 代表的对象返回出来!但如果我们写了 return 语句,如果 return 是基本类型,会被认为写错了无效。obj1 和 2 还是 this 代表的对象。如果 return 是对象,那构造的对象就等于 return 后面的对象。//obj1={a:1,b:2} obj2={a:1,b:2}
三、原型和原型链
1、查找数组 valueof 方法,讲原型链
所有数组都是由 Array 这个函数构建的。数组的所有方法都是 Array.prototype 或者他们的原型链上面的。当我们直接赋值的方式生成一个数组的时候,就相当于直接用 new Array 的方法构建一个对象
Array 函数也是由 object 函数构建的 Array instanceof Object===true
数组可以调用 valueof 这个方法,但 valueof 这个方法不在 Array.protototype 内而是在 object.prototype 内。首先 a 数组 会找自己的 valueof 方法;没有找到,就会沿着__proto__ 属性继续到构造函数 Array 的 prototype 里找 valueof 方法;如果还是没有找到,再继续往 Array.prototype 的 proto 即 Object.prototype 找 valueof 方法,最后找到 valueof 方法。
总结:一个对象调用其方法,先在自己的自由属性内去找,找不到就去原型上去找,如果原型内也找不到,就到原型的原型上去找,直到找到该方法。而这构成的链就是原型链。如下图
2、关于原型链的规律总结
当 new 一个函数的时候会创建一个对象,『函数.prototype』等于『被创建对象.__proto__』
一切函数都是由 Function 这个函数创建的,所以『Function.prototype === 被创建的函数.__proto__』
一切函数的原型对象都是由 Object 这个函数创建的,所以『Object.prototype === 一切函数.prototype.__proto__』
建议阅读若愚老师这边文章里面的例子,巩固印象对原型、原型链、Function、Object 的理解