前端自学之路 Javascript 行话浅析(一)——字面量 包装对象 作用域


本篇主要涉及较为基础的, 变量, 作用域方面的名词。
为啥要知道这些名词的确实含义?

提升自学效率
应付考试
装逼

比如 js权威指南一书中多次提到“直接量” 还有“对象的直接量用法”之类的,如果每次都度娘,浪费时间不说,老是看书卡住然后再度娘,还徒增挫败感,说不定还记不住。所以就需要我们能够提前了解一些名词,为自学相关领域铺平道路。毕竟,学过基本js的行话(概念),看js红宝书,乃至vue react有关的书籍就不容易卡壳了)

直接量(literal)

程序中直接使用的数据值,没啥了不起的。
有时又称为“字面量”,如对象字面量。

下面列举一些直接量:

直接量 实例
数字 1.2
字符串 “Hello world”
布尔 true
正则表达式 /javascript/gi
数组 [1,2,3,4]
对象 {id:1, title:}
未定义的变量 undefine
不存在的对象 NULL

广义上undefine和null也算,至于为什么请看下一节。
当然了这些都无关紧要。
《Javascript语言精粹》一书中采用的插图

Undefine NULL

如果一个值定义了,却没有具体值,类似于NaN,那就称为Undefine。
类似的,我们如果想寻找一个对象,可是它确实“找不到的”,比如可能是,所寻找的对象根本不存在,或者不在同一个域,那返回的结果就是NULL(类似“查无此人”)。

typeof(null) // 结果是‘Object’ 

当然实际中运用还要进一步判断是null(找不到的对象)还是普通的对象直接量

其实根本区别就是你原本想寻找的种类(变量 值还是对象)不同,JS反馈给你“找不到”,这个结果的表达方式的不同。其他深层次还有别的问题,但我们其实碰不到太多。

包装对象

//测试环境 Chrome F12 console 
var s1 = "Hello Vue";
var s2 = s1.substring(s1.indexOf(" ")+1, s1.length);
s1;			//"Hello Vue"
s2;			//"Vue"

本章第一节说,字符串属于直接量,程序直接使用,意味着人家并不是对象,那咋会有方法呢?

什么东西才有方法?
他是个对象
他有属性
他的其中一个属性是个函数
那个函数称为对象的方法

不单单字符串,数字布尔值等直接量都会有这类现象。(当然,上一节的分析告诉我们,这个现象不包含undefined和NULL)

这就是js灵活的地方
JS:“你想要用方法处理这些直接量是吧?让字符串小写变大写,反序啥的,再得到结果?,好的,我帮你暗箱操作一下就行了”。
JS:“反正结果正确就行了”
JS:“什么?只有对象能用?那怕啥,我神不知鬼不觉的生成一个临时对象就可以用了嘛”
(所谓临时对象就是 临时的包装对象
JS:“到时候用完了我再 销毁证据就行了”
(就是把临时的包装对象销毁 至于具体实现时是啥时候销毁 未可知也 但是,你暗箱操作完就不能用了)
JS:“啥?你怕证据会被查到?来来来,我们看看我上次的杰作:”

var string_1 = "test";
string_1.len = 4; //我“留下的操作痕迹”
var What_I_Want = string_1.reverse();//我想要的信息已经转移到我账户了
var attribution_1 = string_1.len; //政府审计在查询属性......

JS:“他绝B审查不出来!(attributon_1 === undefined) == True”

这里,为啥改不了呢?
你更改的不过是他的包装对象。
所以直接对直接量操作方法,其实只能获取信息而并不能改变,这也是js一个规矩——数值 布尔 字符串不能直接改变

前面提到“临时的包装对象”,那自然有真正的,持久的包装对象,就是我们直接,显式装换得到的:

var str_1 = "test", num_1 = 1, bool_1 = true;
var strObject = new String(string_1);
var numObject = new Number(num_1);
var bollObject = new Boolean(bool_1);

这些String() Number() Boolean()将常量转为包装对象
JS通人性的地方不仅仅是说,机智的知道你想像操作对象一样操作常量,比如,他还知道转换后的包装对象和之前的常量大致是一个东西。当然,你硬要区分,就用‘===’就ok了。

strObject == str_1;
//true
strObject === str_1;
//false

变量作用域

就是区域,一块地儿。
假设变量们都成家立业了,互相之间走亲戚需要知道地址,那么全局变量是最骚的——谁都知道他的地址(全局作用域,在代码中任何地方都有定义,都能访问)。
局部变量比较保守,“我只在自己的圈子里,自己人才知道我的地址”(局部作用域)。
不扯了2333.
我们知道变量声明推荐用的是var str_1, 不用会咋样?不好意思,有时候JS不知道你是声明+初始赋值,还是改变已有变量的值:

var global_varible = "我是国际老鼠";
function checkScope(){
	scope = "我是本地老鼠";
	return scope;
}
checkScope()  // => "我是本地老鼠"

为啥国际老鼠(全局变量)变成本地老鼠了(局部变量)?
JS:“我鬼知道scope = ‘我是本地老鼠’ 这句是改变全局的那个scope还是局部的scope?”

所以,为了您的身心健康,声明变量用var, 除非你不是在声明变量2333。

这里有个嵌套(nested)demo:

var mouse = "International mouse";
function ChinaMice(){
	var mouse = "Chinese mouse";
	function BeiJingMice(){
		var mouse = "BeiJing mouse";
		return mouse;
		}
	return BeiJingMice();
}
var Who = mouse; //还是国际老鼠
ChinaMice() //北京老鼠还是中国老鼠还是国际老鼠?

函数作用域 块级作用域

函数作用域(function scope) 就是JS采用的作用域:我函数无论声明在代码的最后还是最前,整个作用域都能访问到我。这个很人性化,
但是,“C语言不是这样的吧?”
“C语言必须把函数声明放最前面,后面的弟弟们才能访问到它。”
对,所以c语言就不是函数作用域。
而JS就被非正式的称为有“变量提前”的特性。
但私以为 最好为了反映真实的变量作用域,将变量放最前面。
想像一下,

var mouse = "国际老鼠";
function(){
	console.log(mouse);
	/*...
	...
	...
	...
	... n行代码 ...
	*/
	var mouse = "本地老鼠";
}

其实你本来想用一下全局变量国际老鼠的,你的猪队友在你后面没事又声明了一下,你就只能获得 undefined了!注意,连本地老鼠都不是哟。所以团队协作就统一口径在 作用域最前面来声明变量。
为什么不是“本地老鼠”?变量声明的确是提前,然并暖——赋值还是老地方,因此,声明和赋值地方不在一起,而且声明不放最前面,你看你队友不打死你:)

块级作用域(block scope),这个在ES6终于支持了,明显,因为我们函数作用域,导致一系列的弊端,之前说的局部未赋值变量随便就覆盖了全局变量,还有局部变量泄漏到全局作用域去,污染了全局作用域,如下栗子:

var str_1 = "mouse";
for (var i = 0;i < str_1.length; i++){
    console.log(str_1[i]);
}
console.log(i); //5

那么我们用let 也就是ES6出来的,支持块级作用域的方式,看看效果:

var str_1 = "mouse";
for (let i = 0;i < str_1.length; i++){
    console.log(str_1[i]);
}
console.log(i); //undefined

还有一种语句块(block)的形式:

    {
        let  t= 1;
        t = t * t +1;
    }
    console.log(t); // undefined

是block结合let的效果,非常人性化。

作用域链 变量解析 引用错误

可以想象,父作用域包着子作用域,子作用域包着孙作用域…这就有点类似一个链条,大环扣小环。那么抽象这个链条有啥子用呢?
答案昭然若揭:
装逼
其实是为了变量解析(varible resolution)
我们JS工作的时候,遇到一变量,比如X,就要去找他的值(解析他,也就是想知道:“X是个嘛玩意儿”),如果孙子作用域没有,就在儿子作用域找,儿子没有找老爸,老爸没有找爷爷, etc, 找呀找呀找朋友找变量的过程称为变量解析(varible resolution),而找的方法就是沿着作用域链
找到祖宗都找不到呢?这是就会报错:引用错误(ReferenceError)

[1]: 《Javascript 权威指南(第六版)》.(美)David.Flanagan.
[2]: 《JavaScript高级程序设计(第三版)》.(美)Nicholas C.Zakas.
[3]: 《Javascript语言精粹》.(美)Douglas Crockford

发布了8 篇原创文章 · 获赞 7 · 访问量 209

猜你喜欢

转载自blog.csdn.net/weixin_43178828/article/details/104016673
今日推荐