关于javascript:我所了解的-JavsScript

39次阅读

共计 3322 个字符,预计需要花费 9 分钟才能阅读完成。

引言

JavaScript 是每个程序员无奈回避的编程语言。它依靠浏览器的反对,牢牢占据着前端编程的市场,又凭借 nodejs,在服务端编程也占有一席之地。很多程序员对它是爱恨交加,爱它的灵便不便,恨它过于灵便的类型转换,简单的包治理等等。明天,我想以一个 非 JavaScript 程序员的角度,来聊聊我所理解的 JavaScript,作为这些年来对它重复浅尝辄止的一个总结。

网页

最早接触到 JavaScript,是十多年前的 QQ 空间。过后的 QQ 空间是一个粗劣的网页,能够由用户自行设置,难看的打扮须要用 Q 币购买,或者充值黄钻能力取得。而很多人不想充钱,又想让本人的空间不那么一般,于是有人发现间接在地址栏输出一段神秘代码,就能获取打扮。那时网上最常被搜寻的就是“QQ 空间打扮代码”。具体的原理我也没搞清,到底是开发人员成心留的收费打扮,还是被人找到了后门。总之,起初我在晓得,那些代码里有些就是 JavaScript。

工夫再往前追溯,到互联网刚刚呈现的年代,最早的网络只有 HTML,毕竟网速和显示设施的限度摆在那里,人们对于能看到纯文字的网页曾经很惊奇了。起初慢慢地人民大众对于美好生活的谋求进步了,相应地网页也要有更丰富多彩的成果。于是有了 CSS 款式,再起初,人们想在浏览器里运行代码,换句话说,在用户的设施上间接运行通用的代码。于是呈现了各种备选项,比方 Java 等等。最初是网景公司推出的 JavaScript 取得了最宽泛的采纳,这个名字据说也是为了蹭当年 Java 的热度。

为了让普通人最快速度上手,获取最多的用户,JavaScript 也有了一些非凡的适配,例如在语法上,字符串能够用单引号,也能够用双引号;表达式的开端能够加分号,也能够不加分号。这样防止了程序员因为语法上的好恶而放弃这门语言。

在性能上,提供方便的类型转换,数字、数组、函数都能够间接被 + 转换为字符串:

let a = 1;
a += "2"   // '12'

let b = [1, 2, 3];
b += "2"   // '1,2,32'

let c = () => {};
c += "2"   // '() => {}2'

这样的设计兴许是因为网页是须要显示给用户看的,数据被转换为字符串,是一种常常会应用到的操作。

OO

忘了是在什么时候,可能是刚刚接触编程的时候吧,就经常听到人说起:“JavaScript 外面一切都是对象”,那时候搞不懂啥是对象。当初我违心将其了解为一种相似哈希表的构造,外面有一些预制的项,例如,.constructor.name 就示意这个对象是由哪个类创立的,默认是 “Object” 类。数字是 “Number” 类,false 是 “Boolean” 类。但我当初至多能够举出两个例子来反驳下面这种论断,undefinednull 都不是对象。

Object Oriendted(面向对象)的编程概念是由 Alan Kay 提出的,最早如同使用于 SmallTalk 语言外面。强调的是在编程时模仿事实世界的物体,比方汽车,苹果,动物等等,都能够看作是一个对象,对象之间通过消息传递来交换。JavaScript 外面有多少真正应用了面向对象的准则我不敢说,集体感觉,除了应用了 Object 这个名字,其它和面向对象的本意仿佛没有多少关系,当然,面向对象和编程里的一些其它概念一样,早已重大偏离了其本意。

在 JavaScript 里有两种赋值,一种是值(value)传递,一种是援用(reference)传递。根底的数据结构,例如数字,布尔值,undefined,null是应用值传递,即赋值到新的变量时,是新建了一个数据, 与原来的数据再无瓜葛:

let a = 9;
let b = a;
a += 1; // 10
b // 9

而那些更简单的对象,都是应用援用传递,即把数据的地址传递给新变量,相当于变量只不过是拜访数据的一个入口,而不是数据自身:

let a = {x: 1};
let b = a;
a.x += 1;
b.x  // 2

这种对 reference(援用)的大量应用,仿佛曾经成为了面向对象的标志性特色。借助这种机制,程序员能够很不便地操作多个关系盘根错节的对象,这种状况在网页编程中非常常见。所以,也能够说是 JavaScript 为了适应网页编程而做出的设计。比方,一个页面上可能有十几个按钮,十几个输入框,各种文本框,它们之间可能存在简单的交互,这时这种隐式指针操作起来就很不便:

let a = {x: 1}
let b = {child: a}
b.child.x += 1;
a.x // 2

函数

函数有什么特地的,哪个语言外面没有函数是吧?JavaScript 的函数也不例外,咱们晓得在一些别的语言里是有 Module(模块)这种货色的,函数必须定义在某一个模块外面。JavaScript 其实也差不多,函数必须属于某一个对象。有人说不对啊,我间接写一个:

function f() {}

this

这样的函数是不是不属于任何对象呢?不是的,因为 JavaScript 自身是有一个全局的对象,在浏览器里就是 window, 在 nodejs 里我不晓得是什么,但必定也是有一个全局对象的。在函数外面,应用 this 就能够拜访它所在的对象:

let a = {
    name: "a",
    f: function() {return this.name}
}

a.f() // 'a'

但要留神的是,JavaScript 的函数分为两种,function函数和箭头函数,箭头函数无论在哪里被调用,外面的 this 都是其定义时所在定义域(scope)的this

let a = {
    name: "a",
    f: function() {return () => this.name
    }
}

a.f()() // 'a' function 函数捕捉了外层的对象,赋值到其定义域内的 this 上,外部的箭头函数继承了这一 this

定义域 scope

这里顺带提一嘴定义域的概念,在 JavaScript 外面,只有 Function 可能发明本人的定义域:

let a = {x: x = 1}

x // 1  一般对象是无奈发明定义域的,所以咱们可能从内部拜访到 x

let f = () => {y = 1}

y //  y is not defined  函数能够发明本人的定义域,从内部无法访问到

class 也是一种 Function。这个在其它语言里也算是比拟常见的设计,将数据类型分为两大类:函数和值。对象是属于 这一类的。

闭包

JavaScript 的 mutable 属性还导致函数有了一种神奇的玩法,也是面试官最爱 —— 闭包。说实话我感觉这货色个别人用不好,但不障碍大神们把它玩出花来。简略来说,咱们能够发明一个函数,同时发明一个只有这个函数可能拜访的变量:

let add = (() => {
    let x = 0;
    return () => x += 1;})();

add() // 1
add() // 2

这基于的还是 Function 的 scope 规定:函数体内定义的变量,在函数体外无法访问。这有什么益处呢?就是在其余语言外面有相似“private”关键词,能够定义对象公有的项(field),而 JavaScript 是没有这种货色的,对象所有的项都是公开的。闭包使得 JavaScript 里也能够有公有项。

event loop

最初聊聊我了解的 event loop 吧。因为 JavaScript 个别状况下是单过程运行的,这个过程有一个音讯队列,运行时会不定期地查看音讯队列里的音讯,或者说事件(Event),依照 FIFO 的程序来解决这些事件:

setTimeout(() => console.log('1'))  // 塞进 mailbox
setTimeout(() => console.log('2'))  // 塞进 mailbox
console.log('0') // 打印
// 终于有工夫能够查看 mailbox

// 0
// 1
// 2

个人感觉 JavaScript 是把单过程的能力开发到了极致,提供了各种语法和工具来不便程序员在单过程的前提上来写异步的代码。这不失为一条独特的路线。

总结

我很喜爱 JavaScript 这门语言,它简单明了,易于上手。只管在平时工作中我用它的机会不多,但在须要时,它总能帮我很快地解决问题。也是因为它的灵活性,暗藏了一些坑,一不留神可能踩进去,我的倡议是对于第三方库要审慎应用,多写测试用例。

本文参加了 SegmentFault 思否写作挑战赛,欢送正在浏览的你也退出。

正文完
 0