您的位置:首页 > Web前端 > JavaScript

JavaScript语言精粹——特性

2016-04-06 20:08 316 查看
1.优美的特性包含于作者的精简的JavaScript中...主要内容
<1>函数是头等对象,在精简JS中,函数是有词法作用域的闭包。
<2>基于原型继承的动态对象
对象是五类别的,可以通过普通的赋值给任何对象增加一个新成员元素。一个对象可以从另一个对象继承成员元素。
<3>对象字面量和数组字面量

对创建新的对象和鼠族来说很方便。

2.糟粕
<1>JavaScript中最糟糕的特性是它对全局变量的依赖性。全局变量随着程序变大,会变的难以处理。因为一个全局变量可以被程序的任何部分在任意时间改变,在程序中使用全局变量降低了程序的可靠性,
<2>全局变量使得在同一个程序中曝光运行独立的子程序变得困难,当某些全局变量与子程序中的变量名称相同会产生冲突。
<3>有三种方式定义全局变量
①脱离任何函数安排一个var 语句  var foo=value;
②直接添加一个属性到全局对象上。全局对象是所有全局变量的容器,浏览器中是window.
window.foo=value;
③直接使用未经声明的变量,被称为隐式的全局变量
foo=value;

<2>作用域
①JavaScript采用了C的语法但没有提供块级作用域,代码块中声明的变量在包含此代码块的函数的任何位置都是可见的。
②在大多数语言里,一般来说声明变量最好的地方是在第一次用到它的地方,但在javascript中最好在每个函数的开头部分声明所有变量。

<3>自动插入分号
①javascript试图通过自动插入分号修正有缺损的程序,但可能带来更严重的错误
return 
{status:true};
看起来要返回status成员元素,但自动插入分号会让它返回undefined.但没有任何提醒。如果把{放在上一行尾部可以避免。

<4>保留字
保留字不能被用来命名变量或者参数,当保留字被用作对象字面量的键值时,必须被引号括起来。它们不能被用在点表示法中,所以有时必须使用括号表示法。
object={case:value};//非法             object={'case':value};//ok

<5>Unicode
JavaScript的字符是16位的, Unicode把一对字符视为一个单一的字符,而JavaScript认为一对自负是两个不同的字符。

<6>typeof
typeof运算符返回一个用于识别其运算数类型的字符串,但typeof null返回object而不是null,检测null可以用
my_value===null
typeof不能分辨出null与对象,可以if(my_value&&my_value==='object')来辨别。

<7>parseInt
parseInt是将一个字符串转换为整数的函数,遇到非数字时停止解析,因此parseInt("16")与parseInt("16 tons")解析结果相同,但它不会有提示。
如果字符串第一个字符是0,则会被基于八进制求值,八进制中没有8和9,因此parseInt("08")与parseInt("09")都会产生0作为结果。,因此建议总是提供第二个参数-基数。

<8> +
+运算符可以用于加法运算或者字符串连接,如果其中一个运算数是空字符串,它会把另一个运算数转换为字符串并返回。如果都是数字,返回和。否则它会把两个运算数都转换为字符串并且连接。如果用+做加法运算,必须确保两个运算数都是整数。(用于小数运算非常不精确)

<9>浮点数
二进制的浮点数不能正确处理十进制小数,因此0.1+0.2不等于0.3,但浮点数中的整数运算是精确的,小数表现出来的错误可以通过指定精度来避免。

<10>NaN
①尽管typeof NaN==='number'返回true,但它表示不是一个数字,它是一个特殊的数量值。试图将非数字形式的字符串转换为数字时候会产生。 + "ops"//NaN
②NaN参与的数学运算结果都是NaN,NaN!==NaN //true
③JavaScript提供了isNaN()函数辨别数字与NaN
isNaN('ops');//true     isNaN(NaN);///true
④判断一个值是否可用作数字的最佳方式是使用isFinite函数,它会筛除掉NaN和Infinity,但它会试图把它的运算数转换为一个数字。
function isNumber(value){return typeof value==='number'&&isFinite(value);}

<11>伪数组
①JavaScript没有真正的数组,不用给JavaScript的数组设置维度,而且它们永远也不会产生越界错误,但比起真正的数组,性能比较糟糕。
②typeof运算符不能辨别数组和对象,要判断一个值是否为数组,要检查它的constructor属性
if(my_value&&typeof my_value==='object'&&my_value.constructor===Array){//是一个数组}//对于不同窗口或者帧创建的数组会返回false
③arguments数组不是数组,是一个带有length成员元素的对象,但它不带有任何数组的方法,如果要辨别arguments和数组,可以增加判断条件typeof my_value.slice==='function'

<12>假值
①JavaScript的假值
值                                 类型
0                                 Number
NaN                            Number
""(空字符串)             String
false                          Boolean
null                             Object
undefined                Undefined
②虽然它们都为假,但他们不可互换。
③undefined和NaN并不是常量,它们是全局变量,而且可以改变它们的值,但一定不能这样做。
<13>hasOwnProperty
hasOwnProperty是一个方法而不是一个运算符,所以在任何对象中,它可能会被一个不同的函数甚至一个非函数值所替换。
如stooge.hasOwnProperty=null

<14>对象
JavaScript的对象永远不会有真的空对象,因为它们可以从原型链中取得成员元素。

3.鸡肋
<1>  ==
①全等===与非全等!==运算符会按照期望的方式工作。如果两个运算数类型一致且值相同则===会返回true.  但==和!=只有在两个运算数类型一致时才会正确判断。如果两个运算数类型不同,它们会转换其值的类型。
如""==0,但""!="0"
②传递性是一种编程约定,对任意引用值x,y,z,如果x==y和y==z为true,那么x==z为true.但JavaScript的==运算符有时违背了这一点
false==undefined;//false
false==null;//false
null==undefined;//true
③所有以上的比较如果使用全等运算符都会返回false,建议始终使用全等与非全等运算符

<2> with语句
JavaScript中的with语句本意是快捷的访问对象的属性,但它的结果可能是不可预料的,应该避免使用。
<3>eval函数
①eval函数传递一个字符串给JavaScript编译器并且执行其结果。但使用eval形式的代码会难以阅读,并且显著降低性能,因为它要运行编译器。eval函数还会削弱应用的安全性。Function构造器是eval的另一种形式,也应该被避免使用。
②浏览器提供的setTimeout和setInterval函数,能接受字符串参数或者函数参数,当传递字符串参数时,它们会像eval那样去处理,字符串参数形式也应该被避免使用。

<4>continue
continue语句跳到循环的顶部,通过重构移除一段代码的continue语句后性能都会得到改善

<5>switch贯穿
switch语句中除非明确中断流程,否则每次条件判断后都会贯穿到下一个case条件。

<6>缺少块的语句
if,while,do或者for语句可以接受一个花括号中的代码块,也可以接受单行语句。单行语句可以节约两个字节,但模糊了程序结构。使得在随后的操作代码中可能很容易插入错误。
严格规范并始终使用代码块会使代码更容易理解。

<7>++  --
递增和递减容易促成不谨慎的编程风格,使用时代码往往变得紧密,复杂和隐晦,尽量不用可以使代码更整洁。

<8>位运算符
①JavaScript没有整数类型,它只有双精读的浮点数,因此位操作符将它们的数字运算数先转换为整数再执行运算,然后再转换回去。因此非常慢,JavaScript很少被用来执行位操作②JavaScript程序中&非常容易被误写为&&,位运算符出现在JavaScript中降低了这门语言的冗余度,使得bug更容易被隐藏。

<9>function语句对比函数表达式
①JavaScript既有function语句又有函数表达式,一个function语句就是其值为一个函数的var语句的速记形式。
function foo(){};意思相当于
var foo=function foo(){};
第二种形式能明确表示foo是一个包含一个函数值的变量。
②function语句在解析时会发生被提升的情况,不管function被放置在哪里,它会被移动到定义时所在的作用域的顶层。
③在if语句中使用function语句是被禁止的,因为大多数浏览器允许在if中使用function语句,但解析时的处理各不相同。
④一个语句不能以一个函数表达式开头,因为官方的语法假定以function开头的语句是一个function语句,解决方法是把函数表达式括在一对圆括号中。
(function(){...})();

<10>类型的包装对象
JavaScript有一套类型的包装对象,比如
new Boolean(false)
会返回一个对象,该对象有一个valueOf方法会返回被包装的值,但完全没有必要。
不要使用new Boolean,new Number或者new String,也避免使用new Object和new Array,可以使用{}和[]代替。

<11>new
①JavaScript的new运算符创建一个继承于其运算数的原型的新对象,然后调用该运算数,把新创建的对象绑定给this,这给运算数一个机会在返回给请求者前去自定义新创建的对象②如果忘记使用new运算符,得到的就是一个普通的函数调用,并且this被绑定到全局对象,而不是新创建的对象,意味着当函数去初始化新成员元素时候它将会污染全局变量,而且没有警告。
③打算与new结合使用的函数应该命名为首字母大写的形式,并且首字母大写的形式应该只用来命名那些构造器函数。
更好的应对策略是根本不使用new

<12>void
很多语言中void是一种类型,表示没有值。但在JavaScript中,void是一个运算符,接受一个运算数并且返回undefined,没啥用,应该避免使用。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: