什么是面向对象
其特点:封装、继承、多态、抽象
提到面向对象(java),就要知道面向过程(c),
面向过程:过程变成,性能高,相对不易维护,复用,扩展
面向对象:易维护、易扩展、实例化,所以开销大,
var obj1 = {};
var obj2 = Object.create({});
var obj3 = new Object();
// 创建对象的4种方式 var o1 = {name: 'o1'} var o2 = new Object({name: '02'}) function O3(){ this.name = 'o3' } var o3 = new O3() var P = {name: 'o4'} var o4 = Object.create(P) o4.propto = P
// 实例有 o1 o2 o3 o4 // 构造函数有 O3 【任何一个函数只要被new使用了,就可称之为构造函数】 // 原型对象 O3.prototype // 实例属性 o1.proto o2.proto o3.proto o4.proto // 实例 === 构造函数 console.log(o3.proto.constructor === O3)
// 构造函数 === 原型对象 console.log(O3.prototype.constructor === O3)
// 实例 === 原型对象 console.log(o3.proto === O3.prototype)
// 只有实例对象才有__proto__ 构造函数也有__proto__ // 只有构造函数有prototype属性 // console.log(o3.proto.proto.proto === null) // console.log(O3.proto === Function.prototype) // console.log(O3.proto === Function.proto) // console.log(Object.proto === Function.prototype) // console.log(Object.proto === Function.proto) console.log(Function.prototype.proto === Object.prototype)
原型链
原型链
- 创建对象有几种方法
- 原型、构造函数、实例、原型链
- Object.create原理实现
- instanceof原理
- new运算符
创建对象有几种方法
// 第一种
var o1 = {name: 'o1'}
//第二种
var o2 = new Object({name: 'o2'})
//第三种
var O3 = function () {
this.name = 'o3'
}
var o3 = new O3()
//第四种
var o4 = Object.create({name: 'o4'})
原型、构造函数、实例、原型链
实例: o1 o2 o3 o4 构造函数: 定义:O3 任何一个函数只要被new使用了,就可称之为构造函数 特性:函数都有prototype属性,生明函数的时候js自动添加属性 prototype 就是【原型对象】 原型对象,怎么区分,我是被哪个构造函数所引用的呢? constructor属性指向一个函数 构造器 O3.prototype.constructor === O3 O3的原型对象(prototype)的属性(constructor)严格指向函数本身
实例/构造函数/原型对象的关联 构造函数-实例: 构造函数 通过new 与实例关联 构造函数-原型对象:构造函数的原型对象(prototype),通过**属性(constructor)**与函数保持关联 实例-原型对象:o3.proto === O3.prototype
注意点: 函数才有prototype 对象是没有的 只有实例对象才有__proto__, 函数也有__proto__; O3.proto === Function.prototype
o3.proto === O3.prototype o3.proto.proto === Object.prototype o3.proto.proto.proto === null
o3.proto.constructor === O3 o3.proto.proto.constructor === Object
instanceof原理
既:解释: cat instanceof Animate === true cat instanceof Object === true
只要在这个原型链上的构造函数函数,都会被instanceof看作是O3的构造函数 cat.proto === Animate.prototype //true Animate.prototype.proto = Object.prototype // true
cat.__proto__.constructor === Animate //true
cat.__proto__.constructor === Object //false
function instanceOf(left, right) {
let leftValue = left.__proto__
let rightValue = right.prototype
while (true) {
if (leftValue === null) {
return false
}
if (leftValue === rightValue) {
return true
}
leftValue = leftValue.__proto__
}
}
Object.create原理实现
function mycreate (Obj) {
function F() {}
F.prototype = Obj
return new F()
}
var test = mycreate({name: 'test'})
new运算符
var new2 = function(func) {
var o = Object.create(func.prototype)
var k = func.call(o)
if (typeof k === 'Object') {
return k
} else {
return o
}
}
function M() {
this.name = 'm'
this.age = '12'
return {
name: this.name,
age: this.age
}
}
o6 = new2(M) //
- 首先创建一个空的对象,空对象的__proto__属性指向构造函数的原型对象
- 把上面创建的空对象赋值构造函数内部的this,用构造函数内部的方法修改空对象
- 如果构造函数返回一个非基本类型的值,则返回这个值,否则上面创建的对象
function _new(fn, ...arg) {
const obj = Object.create(fn.prototype);
const ret = fn.apply(obj, arg);
return ret instanceof Object ? ret : obj;
}
// 实例|构造函数|原型 关系
// 构造函数:
function Animate (name) {
this.name = name
}
Animate.prototype.getName = function(){
return this.name
}
// 实例:
var cat = new Animate
// 实例 - 构造函数
cat.__proto__.constructor === Animate
// 构造函数 - 原型
Animate.prototype.constructor === Animate
// 原型 - 实例
Animate.prototype === cat.__proto__