整理一下JavaScript中一些概念性的东西

一些很基础的东西,在看源码啥的时候可以明白很多
在这里敲一敲code一哈
看到哪里写到哪里吧


作用域

var a = 10; // 全局作用域
(function() {
    var b = 20; // 局部作用域
})();
const arr = [1, 2, 3];
for(let i = 0; i < arr.length; i++) {
    ...
}

变量提升

alert(x) // function;

var x = 10;
alert(x) // 10
x = 20

function x() {}
alert(x) // 20

this

es3/es5this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,this永远指向的是最后调用它的对象

es6箭头函数中this的指向,是定义时this的指向(this用的是已经声明好的this)

var obj = {
    props: 99,
    func: function(){
        return this.props
    }
};

console.log(obj.func()); // 99

// -------------------再来一个-------------------------//
var obj1 = {
    bar: function() {
        return this.baz
    },
    baz: 1
}

(function(){
    console.log(typeof arguments[0]()) // undefined
})(obj1.bar)

// 注意调用obj1.bar的是arguments,所以this是指向arguments的
// 如果在传参的时候调用obj1.bar()的话,则会输出 number
function MyClass(){
    this.a = 99;
};

var obj = new MyClass()

console.log(obj.a) // 99

call和apply的作用是一样的,都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

不同的是apply接受一个数组,而call接受单独的参数

function add (c, d) {
    return this.a + this.b + c + d
};

var obj = {
    a: 1,
    b: 2
};

add.call(obj, 3, 4); // 1+2+3+4 = 10

add.apply(obj, [3, 4]); // 1+2+3+4 = 10

// 可以看出,add中的this是指向obj的
// 因为它可以改变方法中的this,所以能调用call和apply的只有方法

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

var altwrite = document.write;
altwrite("hello");
//报错,因为altwrite方法是在window上进行调用的,而window上是没有该方法的

//正确方法是
altwrite.bind(document)("hello")

闭包

原型

prototype和__proto__ 略探一二

    var a = {}
    console.log(typeof a.prototype)  // undefined

    var a1 = function(){}
    console.log(typeof a1.prototype)  // object

    var B = function(){}
    var b = new B() 
    console.log(typeof B.prototype)  // undefined

继承

function GirlFriend(name, from) {
    this.name = name;
    this.from = from;
    this.alertName = function () {
        alert('my name is' + this.name);
    }
    this.alertFrom = function () {
        alert('I come from' + this.from);
    }
}
 
function myDream(name, from, age) {
    GirlFriend.call(this, name, from);
    // GirlFriend函数在当前this下执行
    // GirlFriend中的this指向了当前的this
    // 也是就指向了myDream,所以myDream可以继承到GirlFriend中的属性和方法
    this.age = age;
    this.alertAge = function () {
        alert(this.age);
    }
}
 
var fack = new myDream("Black Widow", "China", "18");
fack.alertName();//Black Widow
fack.alertFrom();//China
fack.alertAge();//18

普通事件与绑定事件的区别–事件委托

普通事件只支持单个事件,而事件绑定可以添加多个事件

<button id="btn"></button>
<script type="text/javascript">
    var btn=document.getElementById("btn");
    // 普通事件:
    btn.onclick=function(){
        alert("普通事件1");
    }// 不执行
    
    btn.onclick=function(){
        alert("普通事件2");
    } // 执行

    // 绑定事件:
    btn.addEventListener('click',function(){
        alert("绑定事件1");
    },false); // 执行

    btn.addEventListener('click',function(){
        alert("绑定事件2");
    },false); // 执行
</script>

一篇对事件委托的文章