你真的懂Object吗

171 阅读3分钟

1. 封装和继承

  • 并不是封装继承和多态,而是写代码的套路问题(定势思维)

2. 原型链(对象与对象关系)

2.1 七种数据类型

  • 基本类型,存值:number/string/bool/undefined/null/symbol
  • 引用类型,存内存地址:object

2.2 原型链

2.2.1 具体对象的__proto__/[[Prototype]]
  • __proto__这个属性其实指向了[[Prototype]],但是[[Prototype]]是内部属性,我们并不能访问到,所以使用__proto__来访问
var obj = {'name': 'a', age: 18}
var obj2 = {name: 'b', age: 20}
console.dir(obj)
console.dir(obj2)
obj.__proto__ === obj2.__proto__  // true

// 写入一个属性
obj.__proto__.gender = '男'
boj2.gender   // '男'

image.png

image.png

2.2.2 Object的prototype
window.Object.prototype
obj.__proto__ === Object.prototype  // true
arr.__proto__ === Array.prototype // true
pro.__proto__ === Promise.prototype  // true
arr.__proto__.__proto__ === Object.prototype // true
Array.__proto__ === Object.prototype // false
Array.prototype.__proto__ === Object.prototype // true
Function.prototype.__proto__ === Object.prototype // true

image.png

3. this(对象与函数联系)

  • 函数是一种可执行代码(eval执行字符串)组成的对象
var obj = {
  name: 'paul',
  sayName: function() {
    console.log('I am', this.name)
  }
}
obj.sayName()   // I am paul 隐式指定this
obj.sayName.call()  // I am
obj.sayName.call({name: 'james'})  // I am james
var baba = {
  name: 'Mayun',
  child: {
    name: 'Sicong',
    sayName: function() {
      'use strict'   // 非严格模式 call,不传this,会给window,严格模式给undefined
      console.log(this.name)
    }
  }
}
baba.child.sayName()  // Sicong
baba.child.sayName.call()  // name -> undefined
baba.child.sayName.call(baba)  // Mayun
  • 箭头函数的this,找上级
  • this执行时候才能确定

4. bind

  • bind方法创建一个新的函数,当被调用时,将其this关键字设置为提供的值
  • bind参数也是this,参数,非调用,创建了新函数

5. new

  • 批量创建对象
  • 匿名函数新创建堆,有名函数可以复用
  • 返回新对象的函数就是构造函数
  • JS 的 new 到底是干什么的?
  • 构造函数首字母大写
  • 如果构造函数没有参数,那么可以省略括号 new XXX
// 习俗
1. 构造函数首字母大写
2. 构造函数可以省掉 create
3. 如果构造函数没有参数,那么可以省略括号
function Soldier(name){
    this.ID = i // ID 不能重复
    this.生命值 = 42
    this.name = name || '无名战士'
}
// createSoldier.prototype = {constructor: createSoldier}
Soldier.prototype.兵种 = "美国大兵"
Soldier.prototype.攻击力 = 5
Soldier.prototype.行走 = function(){ /*走俩步的代码*/},
Soldier.prototype.奔跑 = function(){ /*狂奔的代码*/  },
Soldier.prototype.死亡 = function(){ /*Go die*/    },
Soldier.prototype.攻击 = function(){ /*糊他熊脸*/   },
Soldier.prototype.防御 = function(){ /*护脸*/       }

var soldiers = []
for(var i=0; i<100; i++){
    soldiers.push( new Soldier )   // Function里私有属性,prototype共有属性
}

兵营.batchMake(soldiers)

6. 继承的写法

士兵 extend 人类
s = new 士兵
// s有人类的属性
// 继承
function Human(options){
	this.name = options.name
	this.肤色  = options.肤色
}
Human.prototype.eat = function(){}
Human.prototype.drink = function(){}
Human.prototype.poo = function(){}

function Soldier(options){
	// this.__proto__ = Soldier.prototype
    Human.call(this, options)
	this.ID = options.ID
    this.生命值 = 42
}
// createSoldier.prototype = {constructor: createSoldier}

// ie兼容写法
// function fakeHuman(){}
// fakeHuman.prototype = Human.prototype
// Soldier.prototype = new fakeHuman()

// no-ie 不兼容ie
Soldier.prototype = Object.create(Human.prototype)
// 脑中的
// Soldier.prototype.__proto__ === Human.prototype

Soldier.prototype.兵种 = "美国大兵"
Soldier.prototype.攻击力 = 5
Soldier.prototype.行走 = function(){ /*走俩步的代码*/},
Soldier.prototype.奔跑 = function(){ /*狂奔的代码*/  },
Soldier.prototype.死亡 = function(){ /*Go die*/    },
Soldier.prototype.攻击 = function(){ /*糊他熊脸*/   },
Soldier.prototype.防御 = function(){ /*护脸*/       }
// Soldier.prototype.__proto__ = Human.prototype

var s = new Soldier({name: '方方', 肤色:'yellow', ID: 1})

// 1. __proto__ js不能用
// Soldier.prototype.__proto__ = Human.prototype
// Soldier.prototype.__proto__ === this.__proto__ === Human.prototype
  • class写法
    • extends只继承公有属性
    • super的意思是call调用一下父类Humen
class Human{
	constructor(options){
		this.name = options.name
		this.肤色  = options.肤色
	}
	eat(){}
	drink(){}
	poon(){}
}

class Soldier extends Human{
	constructor(options){
	  super(options)
		this.ID = options.ID
	  this.生命值 = 42
		this.兵种 = "美国大兵"
		this.攻击力 = 5
	}
	行走(){ /*走俩步的代码*/}
	奔跑(){ /*狂奔的代码*/  }
	死亡(){ /*Go die*/    }
	攻击(){ /*糊他熊脸*/   }
	防御(){ /*护脸*/       }
}
var s = new Soldier({name: '方方', 肤色:'yellow', ID: 1})

image.png