JavaScript基础知识点

118 阅读2分钟

一. 构造函数

// 一般构造函数首字母大写
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