开头
这一章主要讲了3个问题
- 变量
- 类型判断
- 作用域
变量。
基础类型 & 引用类型。
基础类型 在栈里面。
引用类型 站里面放个地址,堆里面放实际内容。
感觉像 .net 值类型和引用类型.
引申出来的问题就是。
引用类型 基础类型复制的问题.
理论上复制都是在 栈 上面.
值类型 都是在 栈 上. 所以每次复制都新的.
var i = 0;
var ii = i;
ii = 1;
console.log(i);
console.log(ii);
结果 自然是 0 & 1.
引用类型 他在桟上只是一个引用. 实际内容却是 堆内存上.
所以 你复制 引用类型的时候,只是复制了一个引用。 实际上,你们指向的是同一个地址.
var o = { a: 1 };
var o1 = o;
o1.a = 2;
console.log(o.a);
console.log(o1.a);
结果 2,2.
就是这样。
貌似有种说法叫做 深复制 & 潜复制
就是针对引用类型.
潜复制 就是刚才那种简单的复制。引用地址还是一样。
深复制 就是在堆内存的数据都复制一份,变成两个完全独立的个体
书中深入了一下,function 参数问题
var o = {
a: ‘test‘
}
function a(obj)
{
obj.a = ‘test1‘;
}
a(o);
console.log(o);
参数传递 其实就是相当于一次 潜复制。
如果参数是引用类型,里面做出修改在外部调用的时候。是会改变的.
类型判断
以前一般使用 typeOf 然后会得到类型
console.log(typeof(‘sadasd‘))
console.log(typeof({}))
console.log(typeof(function(){}))
console.log(typeof([]))
console.log(typeof(1));
console.log(typeof(NaN));
console.log(typeof(Number.MIN_VALUE));
console.log(typeof(Infinity));
console.log(typeof("123"));
console.log(typeof(true));
console.log(typeof(window));
console.log(typeof(document));
console.log(typeof(null));
console.log(typeof(eval));
console.log(typeof(Date));
console.log(typeof(sss));
console.log(typeof(undefined));
string
object
function
object
number
number
number
number
string
boolean
object
object
object
function
function
undefined
undefined
各种. 主要问题还是 太多object
array 是个 object。
object 是 object.
null 是个 object.
解决这个问题有两种办法.
- 用只有他的属性.
比如 Array。 push方法
if(o.push)
这样就可以判断.
还可以使用 instanceof
if(o instanceof Array)
if(o instanceof RegExp)
就可以了.
作用域
他说了2个概念.
1 执行环境.
首先有一个全局环境 window。
其他都是局部环境.
有一个环境桟这个概念。 进入一个函数时,会将这个函数的环境 push 到环境桟中。
执行完 弹出。 并且销毁 这个函数的环境以及变量.
而window是始终存在,知道网页关闭,浏览器关闭之类的.
2 作用域链
这个比较简单。
每一个函数的执行 会有一个作用域的链。
其中有自身变量,和外部环境。
外部环境也是同样的。
就形成了 这样一级一级的 链条.
上级不能访问下级。 最底层访问所有。的关系.
来个例子.
var a = 1;
function funca()
{
var b = 2;
function funcb() {
var c = 3;
}
funcb();
}
funca();
例子很简单,但是还是能说明问题。
都是先查找自己的环境内部变量,然后找外部。
在后面他提到了。 延长作用域和块级作用域.
他说可以用 try catch & with 来延长作用域
function test1()
{
var qs = "?debug=true"
with(location)
{
var url = href +qs;
}
return url;
}
function test2() {
try {
var aaa = "aa";
} catch (e) {
}
return aaa;
}
这两个都能在 {} 外部访问里面声明的变量. 书中说这是延长了作用域。
可是我觉得 这个是 JavaScript 没有块级作用域导致的.
比如
if(xxx)
{
var a = 0;
}
这个 a 在 { } 以外是能够访问的。 因为 JavaScript 是没有块级作用域的。
他和 {} 以外是一个作用域. 所以你能够访问.
我觉得 with & try catch 是一个道理.