1、javascript优秀的想法包括函数、弱类型、动态对象和富有表现力的对象字面量表示法,那些糟糕的想法包括基于全局变量的编程模型。
2、如果一个数字字面量有指数部分,那么这个字面量的值等于e之前的数字与10的e之后数字的次方相乘。所以100和1e2是相同的数字。
3、switch、while、for和do语句允许有一个可选的前置标签(label),它配合break语句来使用。
4、js可以通过条件语句(if和switch)、循环语句(while、for和do)、强制跳转语句(break、return和throw)和函数调用来改变执行序列。
5、js中6个假值(falsy):
false、null、undefined、空字符串 ' '、数字 0、数字 NaN
6、对象字面量是一种可以方便地按指定规格创建新对象的表示法。属性名可以是标识符或字符串。这些名字被当作字面量而不是变量名来对待,所以对象的属性名在编译时才能知道。
7、对象是属性的容器,其中每个属性都拥有名字和值。属性的名字可以是包括空字符串在内的任意字符串。属性值可以是除undefined值之外的任何值。
8、js包含一种原型链的特性,允许对象继承另一个对象的属性。正确地使用它能减少对象初始化时消耗的时间和内存。
9、原型关系是一种动态的关系。如果我们添加一个新的属性到原型中,该属性会立即对所有基于该原型创建的对象可见。
10、让对象在运行时动态获取自身信息时(也就是反射的概念),关注更多的是数据。使用hasOwnProperty()来排除原型链上的属性。
11、一般来说,所谓编程,就是将一组需求分解成一组函数与数据结构的技能。
12、javascript中的函数就是对象。对象是"名/值"对的集合并拥有一个连到原型对象的隐藏连接。对象字面量产生的对象连接到 Object.prototype。函数对象连接到 Function.prototype (该原型对象本身连接到 Object.prototype)。
13、每个函数对象在创建时也随机配有一个prototype属性。它的值是一个拥有 constructor 属性且值即为该函数的对象。这和隐藏连接到 Function.prototype 完全不同。
14、因为函数是对象,所以它们可以像任何其他的值一样被使用。函数可以保存在变量,对象和数组中。函数可以被当作参数传递给其他函数,函数也可以再返回函数。而且,因为函数是对象,所以函数可以拥有方法。
15、递归函数就是会直接或间接地调用自身地一种函数。
16、作用域控制着变量与参数的可见性及生命周期。
17、js具有函数作用域,定义在函数中的参数和变量在函数外部都是不可见的,而在一个函数内部任何位置定义的变量,在该函数内部任何地方都可见。
18、函数可以访问它被创建时所处的上下文环境,这被称为闭包。
19、闭包的糟糕示例
// 闭包糟糕的示例
// 这里事件处理器函数绑定了变量i本身,而不是函数在构造时的变量i的值
var add_the_handlers = function (nodes) {
var i
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = function (e) {
alert(i)
}
}
}
// add_the_handlers(document.querySelectorAll('.wuzhe'))
// 修正方法一
var add_the_handlers = function (nodes) {
var i
for (i = 0; i < nodes.length; i++) {
(function(j){
nodes[j].onclick = function (e) {
alert(j)
}
})(i)
}
}
// add_the_handlers(document.querySelectorAll('.wuzhe'))
// 修正方法二
var add_the_handlers = function (nodes) {
var helper = function (i) {
return function (e) {
alert(i)
}
}
var i
for (i = 0; i < nodes.length; i++) {
nodes[i].onclick = helper(i)
}
}
add_the_handlers(document.querySelectorAll('.wuzhe'))
20、使用函数和闭包来构造模块。模块是一个提供接口却隐藏状态与实现的函数或对象。通过使用函数产生模块,我们几乎可以完全摒弃全局变量的使用。
21、模块模式的一般形式是:一个定义了私有变量和函数的函数;你用闭包创建可以访问私有变量和函数的特权函数;最后返回这个特权函数,或者把它们保存到一个可访问到的地方。
Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func
}
return this
}
String.method('deentityify', function () {
var entity = {
quot: '"',
lt: '<',
gt: '>'
}
return function () {
return this.replace(/&([^&;]+);/g, function (a, b) {
console.log(a, b)
var r = entity[b]
return typeof r === 'string' ? r : a
})
}
}())
在以上例子中,只有deentityify方法有权访问字符实体表这个数据对象
22、模块模式通常结合单例模式使用。javascript的单例就是用对象字面量表示法创建的对象,对象的属性值可以是数值或函数,并且属性值在该对象的生命周期中不会发生变化。
23、柯里化允许我们把函数与传递给它的参数相结合,产生出一个新的函数
function curry (fn, args) {
// debugger
var length = fn.length
args = args || []
return function () {
var _args = args.slice(0),
arg,
i
for (i = 0; i < arguments.length; i++) {
_args.push(arguments[i])
}
if (_args.length < length) {
return curry.call(this, fn, _args)
} else {
return fn.apply(this, _args)
}
}
}
24、当属性名是小而连续的整数时,你应该使用数组。否则,使用对象。
25、正则表达式中,(?:)表示一个可选的非捕获型分组.通常用非捕获型分组来替代少量不优美的捕获型分组是很好的方法,因为捕获会有性能上的损失