Javascript

原型与原型链

  • 所有对象都有自己的原型,包括原型本身
  • 原型链的顶端 -> Object.prototype
  • 普通函数不写返回值 默认return undefined
  • 构造函数实例化以后返回的就是this
  • _proto_:构造函数实例化出来的对象永远指向构造函数的原型对象
  • constructor:指向创建自己的那个构造函数
  • prototype:每个函数都会有这么一个属性,这个属性指向一个对象,这个对象就叫做原型对象
1
2
3
4
5
6
7
1.Function的__proto__指向其构造函数Function的prototype

2.Object作为一个构造函数(是一个函数对象!!函数对象!!),所以它的__proto__指向Function.prototype

3.所有构造函数的的prototype方法的__proto__都指向Object.prototype(除了Object.prototype自身 -> null)

4.Object.prototype里的_proto_指向null(尽头)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var obj1 = {}

var obj2 = new Object() //公司不用这种


function Obj(){} //前两种_proto_里的constructor都指向Object()
var obj3 = new Obj() //自定义指向自己Obj()

// Object.create(对象,null) 创建对象
function Obj(){}
Obj.prototype.num = 1
var obj1 = Object.create(Obj.prototype)
var obj2 = new Obj() //两者等价

var obj1 = Object.create(null) //{} 纯空对象
obj1.num = 1
var obj2 = Object.create(obj1) //继承关系

! obj._proto_ = obj1 //可以更改不能自造
  • 不是所有的对象都继承与Object.prototype
1
2
3
Number.prototype.toString.call(1)  // "1"

Object.prototype.toString.call(1) // "[Object Number]"

call、apply、bind

  • 更改this指向
1
2
3
4
5
6
7
8
9
function Car(brand,color){
this.brand = brand
this.color = color
}
var newcar = {}
Car.call(newcar,'Benz','red')
Car.apply(newcar,['Benz','red']) //arguments [] 效果一样

fn() -> fu.call() //所有的函数执行都等价于

继承

  • 继承的圣杯模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function Teacher(){
this.tSkill = 'HTML'
}

Teacher.prototype = {
this.pSkill = 'CSS'
}

var t = new Teacher()

function Student(){
this.sSkill = 'Javascript'
}

function Buffer(){} //缓冲中间件
Buffer.prototype = Teacher.prototype

var buffer = new Buffer()
//inherit(Student,Teacher)

Student.prototype = buffer //修改Student上的prototype不会影响到Teacher
Student.prototype.age = 18 //低于Teacher的prototype层级

var s = new Student()

封装buffer

1
2
3
4
5
6
7
8
9
var inherit = (function(){				//模块化  防止全局污染
var Buffer = function(){}
return function(Target,Origin){
Buffer.prototype = Origin.prototype
Target.prototype = new Buffer()
Target.prototype.constructor = Target
Target.prototype.super_class = Orign //继承源
}
})();
1
2
3
4
5
//隐式转换
var obj = {
name:'cny'
}
obj.name -> obj['name']

对象枚举

1
2
3
4
5
6
//for in  既能遍历对象也能遍历数组
for(var key in obj){
// obj.key -> obj['key'] -> undefined

//obj[key]
}

hasOwnProperty

  • 判断对象自身属性中是否具有指定的属性 true | false
  • 排除原型
1
'name' in obj  |  obj['name']

instanceof

  • B构造函数的原型是否在A实例对象的原型链上
1
2
3
4
//判断类型
A instanceof B
A.constructor
Object.prototype.toString.call(A)

this

  • 全局this指向window
  • 预编译函数this指向window
  • apply、call改变this指向
  • 构造函数的this指向实例化对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function Test(){
//隐式
// var this = {
// _proto_:Test.prototype
// }
this.name = 'cny'
}
var test = new Test()

// AO = {
// this:window 预编译
//
// this:{ 构造函数实例化的时候
// name:'cny',
// _proto_:Test.prototype
// }
//}

// GO = {
// Test:function test(){...}
// test:{
// name:'cny',
// _proto_:Test.prototype
// }
// }

callee、caller

1
2
3
4
5
6
7
8
arguments.callee    //引用该函数体当前正在执行的函数   严格模式已删除

var sum = (function(n){
if(n <= 1){
return 1;
}
return n + arguments.callee(n - 1)
})(n);
1
function.caller     //返回调用当前function函数的函数引用

typeof

  • object | function | number | string | boolean | undefined
  • obect里面包含null | 历史遗留问题
  • {} != {} | 引用值对比的是地址
1
2
3
var obj = {}
obj1 = obj
obj1 == obj

三元运算符

1
条件 ? 运算1 :运算2

克隆

  • 浅拷贝
  • 创建的新对象会影响旧对象内的属性值
1
2
3
4
5
6
7
8
9
var obj = {
name:'cny'
}

var obj2 = {}

for(var key in obj){
obj2[key] = obj[key]
}
1
2
3
4
5
6
7
8
9
10
function clone(origin,target){
var tar = target || {}
for(var key in origin){
//剔除原型上的属性
if(origin.hasOwnProperty(key)){
target[key] = origin[key]
}
}
return tar
}
  • 深拷贝
  • 创建的新对象不会影响旧对象内的属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function deepClone(origin,target){
var tar = target || {},
toStr = Object.prototype.toString,
arrType = '[Object Array]'

for(var key in origin){
if(origin.hasOwnProperty(key)){
if(typeof(origin[key] === 'object') && origin[key] !== null){
if(toStr.call(origin[key] === arrType){
target[key] = []
})else{
target[key] = {}
}
deepClone(origin[key],origin[key])
}else{
target[key] = origin[key]
}
}
}
return target
}