܄

JavaScript探秘:夯实基础技艺 严控注意事项

【数据猿导读】 在前端工程师的工作中,有句话值得我们时刻警醒——“基础不牢地动山摇”,掌握好基础才能持续高效率的工作。在达观数据的的前端工作中,面对超敏捷开发的业务需求, JavaScript基础尤为重要

JavaScript探秘:夯实基础技艺 严控注意事项

来源:数据猿  作者:达观数据 赵业辉

在前端工程师的工作中,有句话值得我们时刻警醒——“基础不牢地动山摇”,掌握好基础才能持续高效率的工作。在达观数据的的前端工作中,面对超敏捷开发的业务需求, JavaScript基础尤为重要。达观数据专注于企业大数据技术服务,以独创的多层智能挖掘算法,实现对海量用户行为和文本数据的深入分析和挖掘,为企业提供智能文本分析、精准用户行为建模、个性化推荐、智能搜索等尖端数据挖掘功能。下面我们总结一下 JavaScript 中的基本概念中的技术细节和编码规范。

一、语法

1、区分大小写

一切变量、操作符、函数名都区分大小写。

var a = 1;
var A = 1;

a 和 A 是两个不同的变量。

2、标识符

变量、函数、属性的名字、函数的参数。

按照下列规则组合起来的一个或多个字符

第一个字符必须是字母、下划线、货美元符号

其他字符可以是字母、下划线、美元符号或数字

不能把关键字、保留字、true、false、和用作标识符

最佳实践推荐驼峰命名,如functionName

3、注释

单行注释

// 单行注释

多行注释

/*
*   多行注释
*/

4、严格模式

为 JavaScript 定义了不同的解析和执行模型。严格模式下ECMAScript 3 中的不确定行为将得到处理,对某些不安全操作也会抛出错误。

启用严格模式。

// 页面顶部,添加编译指示到整个脚本
"use strict"

function doSomething() {
  // 函数内部,添加编译指示到单个函数
  "use strict"
  do something
}

5、语句

语句以一个分号结尾,没有分号的语句将由编译器自动确定语句的结束并加入分号。

代码块

{
 代码块内容
}

二、关键字和保留字

使用保留字或关键字可能导致Identifier Expected错误

ECMA3 的关键字

break, do, instanceof, typeof, case, else, new, var, catch, finally, return, void, continue, for, switch, while, debugger(ECMA5新增关键字), function, this, with, default, if, throw, delete, in, try

ECMA3 保留字

abstract, enum, int, short, boolean, export, interface, static, byte, extends, long, super, char, final, native, synchronized, class, float, package, throws, const, goto, private, transient, debugger, implements, protected, volatile, double, import, public

ECMA5 非严格模式下的保留字

class, enum, extends, super, const, export, import

ECMA5 严格模式下的保留字

implements, package, public, interface, private, static, let, protected, yield

veal, arguments严格模式下不能用作标识符或属性名

三、变量

ECMAScript 的变量是松散类型的,可以保存任何类型的数据,每个变量只用于保存值的占位符。

未被初始化的变量会保存为值undefined。

var message;
console.log(message) // undefined

可以在修改变量值的同时修改值的类型。

var message = "hi"; // 字符串
var message = 100; // 数字

使用关键字var定义的变量将成为定义该变量的作用域中的局部变量。

function test() {
  var message = "hi" // 局部变量
};
test();
console.log(message); // error

不使用关键字var定义变量将成为全局变量。

不推荐此做法

在局部作用域中声明的全局变量难以维护。

忽略了操作符var,会由于相应变量不会马上就有定义而导致不必要的混乱。

给未经声明的变量赋值在严格模式下会抛出ReferenceError错误。

function test() {
  message = "hi"; //全局变量
}
test();
console.log(message); // hi

使用一条语句定义多个变量

var a = 1,
  b = 2,
  c = 3;

四、数据类型

ECMAScript中有五种基本数据类型:Undefined、Null、Boolean、Number、String,还有一种复杂数据类型Object,其本质上是由一组无序的键值对组成的。

1、typeof 操作符

检测变量的数据类型

typeof是操作符而不是函数,因此其后的括号不是必须的

var message = ***;
console.log(typeof(message));

undefined:未定义

boolean:布尔值

string:字符串

number:数值

object:对象或Null

function:函数

2、Undefined类型

Undefined类型只有一个值:特殊的 undefined。使用var声明变量但未对其初始化,这个变量的值就是Undefined

var a;
console.log(typeof(a)); // undefined

不推荐使用undefined显式初始化变量。

包含Undefined值的变量和未定义的变量是不同的。

var message; // 这个变量声明后默认得到了 Undefined
console.log(message); // undefined
console.log(a); // error

使用typeof检测未初始化的变量和未声明的变量都会返回undefined。

var message; // 这个变量声明后默认得到了 Undefined
console.log(typeof message); // undefined,未初始化的变量
console.log(typeof a); // undefined,未声明的变量

对尚未声明的变量只能执行一项操作——typeof检测。对其调用delete不会导致错误,但也没有实际意义,而且在严格模式下会报错。

最佳实践:推荐显式初始化变量。在之后typeof操作符返回undefined即可断定此变量未被声明,而不是尚未初始化。

3、Null

Null类型只有一个值:特殊的 null。

从逻辑角度来看,null值表示一个空对象指针,所以使用typeof检测null值会返回object。

var car = null;
console.log(typeof car) // object

如果定义的变量准备在将来用于保存对象,推荐将该变量初始化为null,以后只需要检查null值即可知道其是否已经保存了一个对象的引用。

var car = null;
if ( car =! null) {
  do something for car
}

undefined值派生自null,因此ECMA规定对它们的相等性测试要返回true。

console.log(null == undefined) // true

4、Boolean

该类型有两个字面值:true和false。

Boolean类型的字面值true和false是区分大小写的。

数据类型

转换为true的值

转换为false的值

Boolean

true

false

String

任何非空字符串

空字符串

Number

任何非零数值

0和NaN

Object

任何对象

null

Undefined

n/a(not applicable,不适用)

undefined


ECMAScript中所有类型的值都有与这两个Boolean值等价的值。

5、Number

使用IEEE754格式表示整数和浮点数值。为支持各种数值类型,ECMAScript定义了不同的数值字面量格式。

< >十进制八进制,以0开头,在严格模式中无效,无效的八进制数字将会被当做十进制数值被解析。十六进制,以0x开头默认情况下ECMAScript会将小数点后面带有6个0以上的浮点数值转换为科学计数法表示的数值。浮点数值的最高精度是17位小数,但做算术计算时精度远不如整数值。

存贮位置

数值

超出后

Number.MIN_VALUE

5e-324

Infinity(正无穷)

Number.MAX_VALUE

1.7976931348623157e+308

-Infinity (负无穷)

console.log(isFinite(result)); // false

(3)NaN

NaN(Not a Number),用于表示一个本来要返回数值的操作数未返回数值的情况。

< >任何涉及NaN的操作都会返回NaN。NaN和任何值都不相等。Boolean值,true——1,false——0;数字,传入——返回;null——0;undefined——NaN;字符串只包含数字的字符串——十进制数字;包含有效的浮点格式——对应的浮点数值;包含有效的十六进制——相同大小的十进制整数值;空字符串——0;上述都不符合——NaN。对象——valueOf()按照上述规则返回值valueOf()返回值是NaN——toString()方法按照上述规则返回字符串值。第一个字符不是数字字符或负号,返回NaN。第一个字符是数字字符,会继续解析后续字符,直到解析完所有字符或遇到非数字字符。第一个小数点后的数字有效,第二个小数点后的数字将会被忽略。始终忽略前导的0。十六进制格式的字符串都会被解析为0。如果可以被解析为整数,会返回整数。

字面量

含义

\n

换行

\t

制表

\b

退格

\r

回车

\f

进纸

\\

斜杠

'

单引号,在单引号表示的字符串中使用,'he said,\'hello.\'

"

双引号,在双引号表示的字符串中使用,"he said,\"hello.\""

\xnn

以十六进制代码nn表示的一个字符(n为0~F)

\unnn

以十六进制代码nnnn表示的一个Unicode字符(n为0~F)

 

以上字符字面量可以出现在字符串的任意位置,也会被当做一个字符解析。

console.log('He said, \"hello!\".'.length); // 18

(2)字符串的特点

字符串不可变,被创建后其值不能改变。如果要改变一个变量保存的字符串,首先要销毁原来的字符串,再用另一个包含新值的字符串填充该变量。这也导致了老版本浏览器拼接字符串速度慢的问题。(赵业辉 达观数据)

var lang = 'Java';
lang = lang + 'Script';

< >变量lang包含字符串'Java'创建10个字符的字符串并填充'Java'和'Script'销毁原来的'Java'和'Script'数值、布尔值、对象和字符串都有toString()方法,null和undefined没有。

调用数值的toString()方法时,可以传递输出数值的进制数作为参数,默认为十进制。如果值有toString()方法——调用该方法(没有参数的)并返回相应结果。null —— 'null'。undefined —— 'undefined'。constructor构造函数:保存着用于创建当前对象的函数。var o = new Object()的构造函数就是Object()。

hasOwnProperty(propertyName):检查给定的属性在当前对象实例中(不是在实例的原型中)是否存在。作为参数的属性名必须以字符串形式指定,例如o.hasOwnProperty('properName')。isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型。

propertyIsEnumerable(propertyName):检查给定的属性是否可以使用for-in语句枚举,参数的属性名必须以字符串形式指定。

toLocaleString():返回对象的字符串表示,该字符串于执行环境的地区对应。toString():返回对象的字符串表示。

valueOf():返回对象的字符串、数值或布尔值表示,通常与toString()方法的返回值相同。由一个叹号(!)表示,有一个操作数可以用于任何值。无论这个值是什么数据,其都会返回一个布尔值。

首先将操作值使用Boolean()转换为一个布尔值,再求其反。由两个和号表示(&&),有两个操作数两个操作数都为 true,则返回 true;两个操作数任一个为 false,则返回 false由两个竖线表示(||),有两个操作数两个操作数都为 false 返回false,否则返回true

操作数

返回值

第一个操作数是对象

二个操作数

第二个操作数是对象

只有第一个操作数的求值结果为true 时返回该对象

都是对象

第二个对象

有一个操作数是null

null

有一个操作数是undefined

undefined

操作数

返回值

第一个操作数是对象

第一个操作数

第一个操作数的求值结果为false

第二个操作数

两个操作数都是对象

第一个操作数

两个操作数都是null

null

两个操作数都是NaN

NaN

两个操作数都是undefined

undefined

 

或操作可以用于任何类型。在有一个操作数不是布尔值的情况下,逻辑与操作不一定返回布尔值:

逻辑或与逻辑与相似,都是短路操作符,如果第一个操作数的求值结果为true,就不会对第二个操作数求值。(赵业辉 达观数据)

可以使用逻辑或的这一行为避免为变量赋值null 或undefined:

var backupObject = 'backup value',
  preferredObject;
var myObject = preferredObject || backupObject;
console.log(myObject);
// 'backup value'

操作数

结果

都是数值

正负号相同得正,反之得负;乘积如果超过了 ECMAScript 数值表示范围,则返回Infinity 或-Infinity

一个是NaN

NaN

Infinity * 0

NaN

Infinity * number( != 0)

Infinity 或-infinity

Infinity * Infinity

Infinity

在上例代码中,变量preferredObject 的值会优先赋给myObject,变量backupObject 负责在preferredObject 不包含有效值的情况下提供后备值。如果preferredObject 的值不是null 或undefined,它的值将被赋给myObject,反之会将backupObject 的值赋给myObject。

3、乘性操作符

ECMAScript 中定义了三个乘性操作符:乘法、除法和求模。操作数为非数值的情况下会执行自动的类型转换,即先调用Number()转型函数将其转换为数值。

(1)乘法

乘法操作符由一个星号(*)表示,用于计算两个数的乘积。

在处理特殊值的情况下遵循以下规则:

(2)除法

除法操作符由一个斜线(/)表示,执行第二个操作数除第一个操作数的计算。

除法操作符对特殊值的处理规则:

操作数

结果

都是数值

正负号相同得正,反之得负;乘积如果超过了 ECMAScript 数值表示范围,则返回Infinity 或-Infinity

一个是NaN

NaN

Infinity * 0

NaN

0/0

NaN

Infinity / number( != 0)

Infinity 或-infinity

Infinity / Infinity

NaN

(3)求模

求模(余数)操作符由一个百分号(%)表示。

在处理特殊值的情况下遵循以下规则:

操作数

结果

都是数值

余数

一个是NaN

NaN

Infinity % number

NaN

number % 0

NaN

0/0

NaN

number % Infinity

number

Infinity % Infinity

NaN

0 % number

0

4、关系操作符

包括大于(>)、小于(<)、大于等于(>=)、小于等于(<=)。

console.log(5 > 3);
// true
console.log(5 < 3);
// false

当关系操作符的操作数用了非数值时,转换规则如下:

操作数

操作

两个操作数都是数值

比较

两个都是字符串

比较字符串对应的字符编码值

有一个操作数是数值

将另一个操作数转换为数值再比较

一个操作数是布尔值

转换为数值再比较

一个操作数是对象

先调用valueOf()方法,再按照上述规则比较;没有valueOf()方法则调用toString()方法再按照上述规则比较

比较字母时应先转换为全部大写或全部小写,因为大小写字母的字符编码不同。

5、相等操作符

相等和不相等——先转换再比较。全等和不全等——仅比较不转换。

(1)相等和不相等

相等操作符由两个等于号(==)表示,两个操作数相等返回true。不相等操作符由叹号后跟等于号(!=)表示,两个操作数不相等返回true。这两个操作符都会先转换操作数再比较相等性。(赵业辉 达观数据)

相等操作符和不相等操作符转换规则:

操作数

转换结果

一个操作数是布尔值

数值

一个操作数是字符串,另一个是数值

字符串转换为数值

一个操作数是对象,另一个不是对象

调用对象的valueOf()方法得到基本类型再按照其他规则比较

相等操作符和不相等操作符比较规则:

< >null 和 undefined是相等的。比较相等性之前,null 和undefined 不能转换为其他值。有一个操作符是NaN,返回false,因为NaN不等于任何值。如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等性操作符返回true,否则返回false。'*=''/=''%=''+=''-=''<<=''>>=''>>>='不能把函数命名为 eval 或 arguments不能把参数命名为 eval 或 arguments同一函数内的两个命名参数不能同名

1、参数

ECMAScript 函数不介意传递进来的参数的数量和数据类型,因为 ECMAScript 中的参数在内部是用一个数组来表示的,函数接收到的始终都是这个数组,与数组中有哪些参数无关。在函数体中可以通过arguments 对象来访问这个参数数组,从而获取传递给函数的每一个参数。(赵业辉 达观数据)

arguments对象与数组类似,但它并不是 Array 的实例。在函数体中可以使用方括号语法访问该函数的arguments对象的每个元素,使用 length 属性来获知传递进的参数数量。

根据这个特性,上文中的 hello 函数也可以用下面的方式重写

function hello () {
   alert('Hello ' + arguments[0] + ',' + arguments[0]);
}

重写后的函数不包含命名的参数。虽然没有使用前文中的参数标识符,但是对函数的功能没有影响,这说明了函数中命名的参数只是为了提供便利,但不是必须。

2、重载

ECMAScript 函数不能像传统意义上那样实现重载,只能通过再次定义函数变相地实现重载:

// 第一次声明
function sum(num) {
  return num + 100;
}

//第二次声明实现重载
function sum(num) {
  return num + 200;
}


注:本文由 达观数据 投稿数据猿发布。

欢迎更多大数据企业、爱好者投稿数据猿,来稿请直接投递至:tougao@datayuan.cn


来源:数据猿

声明:数据猿尊重媒体行业规范,相关内容都会注明来源与作者;转载我们原创内容时,也请务必注明“来源:数据猿”与作者名称,否则将会受到数据猿追责。

刷新相关文章

美国大数据行业究竟什么样? 我们带你一探究竟
美国大数据行业究竟什么样? 我们带你一探究竟
数之联CTO方育柯:大数据时代下的传统制造业
数之联CTO方育柯:大数据时代下的传统制造业
明略数据工业大数据专家葛利鹏:大数据驱动的工业人工智能初探
明略数据工业大数据专家葛利鹏:大数据驱动的工业人工智能初探

我要评论

精品栏目

[2017/04/11]

大数据24小时

More>

[2017/04/03-7]

大数据周周看

More>

[2017/04/03-7]

大数据投融资

More>

[2016/11/28-2]

大咖周语录

More>

[2017/04/03-10]

大数据周聘汇

More>

[2017/04/04-11]

每周一本书

More>

返回顶部