JS的基础笔记
学习的时候写了一些笔记,然后就想花时间整理一下,一方面是加深理解和记忆,另一方面是想系统的整理一下,参考的来源我都会写下来。
我的笔记目录
- 原型和原型链
- 作用域和作用域链
- 闭包
1,原型和原型链
1.1 原型
原型:构造函数都有一个原型(prototype),指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承.
访问原型:1,构造函数(constructor)通过.prototype。2,实例通过._proto_,实例会继承原型的属性和方法。
1.2 原型链
比如说,a继承b, b继承c, a的原型就会包含b的原型,b的原型包含c的原型,从来就形成了原型链, 下图Cat继承了animal的原型。打印的是一个Cat实例
参考来源:www.ruanyifeng.com/blog/2010/0…
2,作用域和作用域链
2.1 变量作用域: 变量作用的区域
作用域只作用在函数的内部,外部不可访问
function foo() {
var x = 1;
function bar() {
var y = x + 1; // foo函数内部的bar函数可以访问foo的变量X
}
var z1 = x + 1 // foo函数内部也可以访问foo的变量X
var z2 = y + 1; // ReferenceError! bar函数外部不可以访问bar的变量y!
}
2.2 作用域链 : 从函数内部到外部开始找变量,直到找到为止,如果在window这一层都没有找到,那该变量is not defined
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope(); //local scope
checkscope()先从函数内部开始找scope这个变量,找到了就会停止。所以我们得到的scope是函数内部的scope,如果函数内部没有scope,才会去函数外面找。
var scope = "global scope";
function checkscope(){
function f(){
return scope;
}
return f();
}
checkscope(); //global scope
参考来源:
www.liaoxuefeng.com/wiki/102291…
github.com/mqyqingfeng…
3,闭包
这是一个需要了解内存的问题,js里面的存储方式分两种。还有,我也不懂它为什么要叫闭包,明明是去函数内部偷变量。因为作用域的关系,我们本来是不可以在函数外部访问函数内部的变量,但是通过闭包,可以,偷。
3.1 关于内存 (关联请看下面3.3.2)
数字,字符串,布尔值这类数据类型在内存中存的真实的值,
对象,函数在内存中存的是地址
3.2 闭包是通过其他函数的返回值得到其他函数内部变量的函数
function f1() {
var n = 999;
function f2() {
console.log(n)
}
return f2;
}
var result = f1();
result(); // 999
本来函数外部是不能访问函数内部变量的,闭包就可以把变量拿出来
3.3 闭包的坑点
3.3.1 返回的函数并没有立刻执行,而是直到调用了才执行
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push(function () {
return i * i;
});
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1(); // 16
f2(); // 16
f3(); // 16
执行count函数,返回的是一个函数数组,数组里面的每个函数都还没有被执行,所以匿名函数里面的return i*i是没有执行的,后面执行f1/f2/f3的时候,函数会根据作用域链查找i,而那时i的值已经是4了,所以才会都得到16。如果要固定参数的话,可以按照下面这样
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push((function (n) {
return function () {
return n * n;
}
})(i)); //push进去的是一个执行的匿名函数的返回值,也就是一个有固定参数的函数
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1(); // 1
f2(); // 4
f3(); // 9
3.3.2 函数是一个单独的值,函数在内存存的是地址,它可以在不同的环境(this)执行。所以可能闭包在执行的时候,因为this的不同会导致结果不同。
第一种
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
return this.name;
};
}
};
alert(object.getNameFunc()()) //The Window
第二种
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
var that = this;
return function () {
return that.name;
};
}
};
alert(object.getNameFunc()());//My Object
特别特别需要注意,这两个由object.getNameFunc()得到的函数的this指向全局对象,也就是window。那结果为什么不同,就是因为第二个函数在object.getNameFunc()执行的时候函数的this指向object。如果还不清楚,那就拆开看
object.getNameFunc()() ===(等同于) var fun = object.getNameFunc() fun()
var fun = object.getNameFunc() //只是执行getNameFunc函数,并没有给定fun函数的this指向
fun() // 本来两个函数this都是指向window,第二种在object.getNameFunc()执行的时候函数的this指向Object
参考来源:
www.ruanyifeng.com/blog/2009/0…
(阮一峰老师的网络日志实在是对新手非常,特别,尤其地友好)
www.liaoxuefeng.com/wiki/102291…
(廖雪峰老师的js教程也是很好的,比较全面)