一. 构造函数
// 一般构造函数首字母大写
function Foo(name, age) {
this.name = name
this.age = age
this.class = 'class-1'
// return this // 默认有这一行
}
var f = new Foo('zhangsan', 20)
二. 构造函数-拓展
- var a = {} 其实是var a = new Object()的语法糖
- var a = [] 其实是var a = new Array()的语法糖
- function Foo(){...} 其实是var Foo = new Function(...)的语法糖
- 使用instanceof判断一个函数是否是一个变量的构造函数
三. 原型规则和示例
- 所有的引用类型(数组,对象,函数),都具有对象特性,即可自由扩展属性(除了“null”以外)
- 所有的引用类型(数组,对象,函数),都有一个_proto_属性(隐式原型),属性值是一个普通的对象
- 所有的函数,都有一个prototype属性(显式原型),属性值也是一个普通的对象
- 所有的引用类型(数组,对象,函数),_proto_属性值指向它的构造函数的“prototype”属性值
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会从它的_proto_(即它的构造函数的prototype)中寻找
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;
console.log(obj._proto_);
console.log(arr._proto_);
console.log(fn._proto_);
console.log(fn.prototype);
console.log(obj._proto_ === Object.prototype);
// 构造函数
function Foo (name, age) {
this.name = name
}
Foo.prototype.alertName = function () {
alert(this.name)
}
// 创建实例
var f = new Foo ('zhangsan')
f.printName = function () {
console.log(this.age)
}
// 测试
f.printName()
f.alertName()
f.toString() // 要去 f._proto_._proto_中查找
四. 原型链
五. instanceof
-
f instanceof Foo 的判断逻辑是:
-
f 的_proto_一层一层往上,能否对应到Foo.prototype
-
再试着判断 f instanceof Object
六. 作用域和闭包
1.this
-
this 要在执行时才能确认值,定义时无法确认
-
作为构造函数执行
function Foo(name) { this.name = name } var f = new Foo('zhangsan') -
作为对象属性执行
var obj = { name: 'A', printName: function () { console.log(this.name) } } obj.printName() -
作为普通函数执行
function fn () { console.log(this) //window } fn() -
call apply bind
function fn1(name, age) { alert(name) console.log(this) } fn1.call({x: 100}, 'zhangsan', 20) function fn2(name, age) { console.log(name, age) console.log(this) } fn2.apply({x: 100}, ['zhangsan', 20]) var fn3 = function (name, age) { alert(name, age) console.log(this) }.bind({x: 100}) fn3( ['zhangsan', 20)
2.作用域
-
无块级作用域
if (true) { var name = 'li' } console.log(name) -
函数和全局作用域
var a = 100 function fn () { var a = 200 console.log('fn', a) } console.log('global', a) fn() //global 100 fn 200 -
作用域链
var a = 100 function F1 () { var b = 200 function F2 () { var c = 300 console.log(a) // a 是自由变量 console.log(b) // b 是自由变量 console.log(c) } F2() } F1()
3.闭包
闭包的使用场景
- 函数作为返回值
function F1 () { var a = 100 // 返回一个函数(函数作为返回值) return function () { console.log(a) // 自由变量,父作用域寻找 } } // f1 得到一个函数 var f1 = F1() var a = 200 f1() // 100 - 函数作为参数传递
function F1 () { var a = 100 // 返回一个函数(函数作为返回值) return function () { console.log(a) } } // f1 得到一个函数 var f1 = F1() function F2 (fn) { var a = 200 fn() } F2(f1) // 100