随笔分类 - javascript
摘要:
得担心一种特殊的情况。如果使用单个数字参数来调用Array构造函数,效果完全不同。它试图创建一个长度为给定参数的空数组。这意味着['hello']和new Array('hello'),但[17]和new Array(17)的行为完全不同。
字面量更清晰,更优雅,更不易出错,更规范,更一致。
阅读全文
得担心一种特殊的情况。如果使用单个数字参数来调用Array构造函数,效果完全不同。它试图创建一个长度为给定参数的空数组。这意味着['hello']和new Array('hello'),但[17]和new Array(17)的行为完全不同。
字面量更清晰,更优雅,更不易出错,更规范,更一致。
阅读全文
摘要:
Array.prototype中的方法,这两条都不是必须的,因为在增加或删除索引属性的时候它们都会强制地更新length属性。
Array方法中只有一个不是通用的,即数组连接方法concat。该方法可以由任意的类数组接收者调用,但它会检查其参数[[Class]]属性。如果参数是一个真实的数组,那么concat会将该数组的内容连接起来作为结果;否则,参数将以一个单一的元素来连接。
阅读全文
Array.prototype中的方法,这两条都不是必须的,因为在增加或删除索引属性的时候它们都会强制地更新length属性。
Array方法中只有一个不是通用的,即数组连接方法concat。该方法可以由任意的类数组接收者调用,但它会检查其参数[[Class]]属性。如果参数是一个真实的数组,那么concat会将该数组的内容连接起来作为结果;否则,参数将以一个单一的元素来连接。
阅读全文
摘要:
使用迭代方法替换for循环使得代码可读,并且避免了重复循环控制逻辑
使用自定义的迭代函数来抽象未被标准库支持的常见循环模式
在需要提前终止循环的情况下,仍然推荐使用传统的循环。另外,some和every方法也可用于提前退出
阅读全文
使用迭代方法替换for循环使得代码可读,并且避免了重复循环控制逻辑
使用自定义的迭代函数来抽象未被标准库支持的常见循环模式
在需要提前终止循环的情况下,仍然推荐使用传统的循环。另外,some和every方法也可用于提前退出
阅读全文
摘要:
for...in循环在运行时出错了错误,并没有要求枚举对象的修改与当前保持一致。事实上,ES对并发修改在不同js环境下的行为的规范留有余地。标准规定:
如果被枚举的对象在枚举期间添加了新的属性,那么在枚举期间并不能保证新添加的属性能被访问。
上面规范的实际后果:如果我们修改了被枚举的对象,则不能保证for...in循环的行为是可预见的。
阅读全文
for...in循环在运行时出错了错误,并没有要求枚举对象的修改与当前保持一致。事实上,ES对并发修改在不同js环境下的行为的规范留有余地。标准规定:
如果被枚举的对象在枚举期间添加了新的属性,那么在枚举期间并不能保证新添加的属性能被访问。
上面规范的实际后果:如果我们修改了被枚举的对象,则不能保证for...in循环的行为是可预见的。
阅读全文
摘要:
该方法确保你需要整数索引和数组元素时就能获取到它们,并且绝不会混淆它们或引发字符串的强制转换。此外,它还可以确保正确的迭代数组,并且不会意外地包括存储在数组对象或其原型链中的非整数属性。
阅读全文
该方法确保你需要整数索引和数组元素时就能获取到它们,并且绝不会混淆它们或引发字符串的强制转换。此外,它还可以确保正确的迭代数组,并且不会意外地包括存储在数组对象或其原型链中的非整数属性。
阅读全文
摘要:
之前的几条都不断地重复着for...in循环,它便利好用,但又容易被原型污染。for...in循环最常见的用法是枚举字典中的元素。这里就是从侧面提出不要在共享的Object.prototype中增加可枚举的属性。这就导致,我们在开发的时候,不能在Object.prototype中添加有用的方法。如,我们想增加一个产生对象属性名数组的allKeys方法将会怎么样?Object.prototype.a
阅读全文
之前的几条都不断地重复着for...in循环,它便利好用,但又容易被原型污染。for...in循环最常见的用法是枚举字典中的元素。这里就是从侧面提出不要在共享的Object.prototype中增加可枚举的属性。这就导致,我们在开发的时候,不能在Object.prototype中添加有用的方法。如,我们想增加一个产生对象属性名数组的allKeys方法将会怎么样?Object.prototype.a
阅读全文
摘要:
对象属性无序性 js对象是一个无序属性集合。var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说。for...in循环,先输出哪个属性都有可能。获取和设置不同的属性与顺序无关,都会以大致相同的效率产生相同的结果。也就是说访问属性a和访问属性b,没有哪个访问更快之说。ES标准并未规定属性存储的任何特定顺序,甚至于枚举对象也未涉及。for...in循环会挑.
阅读全文
对象属性无序性 js对象是一个无序属性集合。var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说。for...in循环,先输出哪个属性都有可能。获取和设置不同的属性与顺序无关,都会以大致相同的效率产生相同的结果。也就是说访问属性a和访问属性b,没有哪个访问更快之说。ES标准并未规定属性存储的任何特定顺序,甚至于枚举对象也未涉及。for...in循环会挑.
阅读全文
摘要:
我们是使用dict对象的hasOwnProperty方法,但其实它自身并没有这个方法,而是继承自Object.prototype对象。如果dict字典对象有一个同为"hasOwnProperty"名称的属性,那么原型中的hasOwnProperty方法不会被访问到。这里会优先读取自身包含的属性,找不到才会从原型链中查找。
阅读全文
我们是使用dict对象的hasOwnProperty方法,但其实它自身并没有这个方法,而是继承自Object.prototype对象。如果dict字典对象有一个同为"hasOwnProperty"名称的属性,那么原型中的hasOwnProperty方法不会被访问到。这里会优先读取自身包含的属性,找不到才会从原型链中查找。
阅读全文
摘要:
ES5提供了标准方法来创建一个没有原型的对象。Object.create函数能够使用一个用户指定的原型链和一个属性描述符动态地构造对象。属性描述符描述了新对象属性的值及特性。通过简单传递一个null原型参数和一个空的描述符,就可以建立一个真正的空对象。
阅读全文
ES5提供了标准方法来创建一个没有原型的对象。Object.create函数能够使用一个用户指定的原型链和一个属性描述符动态地构造对象。属性描述符描述了新对象属性的值及特性。通过简单传递一个null原型参数和一个空的描述符,就可以建立一个真正的空对象。
阅读全文
摘要:
js对象的核心是一个字符串属性名与属性值的映射表。使用对象实现字典易如反掌,字典是可变长的字符串与值的映射集合。 for...in js提供了枚举一个对象属性名的利器--for...in循环。var dict={zhangsan:34,lisi:24,wangwu:62}; var people=[]; for(var name in dict){ people.push(name+":"+d
阅读全文
js对象的核心是一个字符串属性名与属性值的映射表。使用对象实现字典易如反掌,字典是可变长的字符串与值的映射集合。 for...in js提供了枚举一个对象属性名的利器--for...in循环。var dict={zhangsan:34,lisi:24,wangwu:62}; var people=[]; for(var name in dict){ people.push(name+":"+d
阅读全文
摘要:
对象是js中的基本数据结构。对象在js语言编码中也随处可见,比如经常会用到的函数,也是一个Function构造函数,Function.prototype原型对象。每当声明一个函数时,都会继承Function.prototype里的方法和属性。当使用"1,2,3".split(',')时,实际是把"123"先转化为String对象,然后调用String对象的原型方法。这些初期时只会用用,但它里...
阅读全文
对象是js中的基本数据结构。对象在js语言编码中也随处可见,比如经常会用到的函数,也是一个Function构造函数,Function.prototype原型对象。每当声明一个函数时,都会继承Function.prototype里的方法和属性。当使用"1,2,3".split(',')时,实际是把"123"先转化为String对象,然后调用String对象的原型方法。这些初期时只会用用,但它里...
阅读全文
摘要:
41条对违反抽象原则行为的讨论之后,下面聊一聊终极违例。由于对象共享原型,因此每一个对象都可以增加、删除或修改原型的属性。这个有争议的实践通常称为猴子补丁。 猴子补丁示例 猴子补丁的吸引力在于其强大。数组缺少一个有用的方法吗?你自己就可以增加它。Array.prototype.split=function(i){ return [this.slice(0,i),this.slice(i)];...
阅读全文
41条对违反抽象原则行为的讨论之后,下面聊一聊终极违例。由于对象共享原型,因此每一个对象都可以增加、删除或修改原型的属性。这个有争议的实践通常称为猴子补丁。 猴子补丁示例 猴子补丁的吸引力在于其强大。数组缺少一个有用的方法吗?你自己就可以增加它。Array.prototype.split=function(i){ return [this.slice(0,i),this.slice(i)];...
阅读全文
摘要:
对象原型链 一个对象给其使用者提供了轻量、简单、强大的操作集。使用者与一个对象最基本的交互是获取其属性值和调用其方法。这些操作不是特别在意属性存储在原型继承结构的哪个位置。随着时间推移,实现对象时可能会将一个属性实现在对象原型链的不同位置,但是只要其值保持不变,那么这些基本操作的行为也不变。原型是一种对象行为的实现细节。 内省机制 js提供了便利的内省机制来检查对象的细节。Object.proto...
阅读全文
对象原型链 一个对象给其使用者提供了轻量、简单、强大的操作集。使用者与一个对象最基本的交互是获取其属性值和调用其方法。这些操作不是特别在意属性存储在原型继承结构的哪个位置。随着时间推移,实现对象时可能会将一个属性实现在对象原型链的不同位置,但是只要其值保持不变,那么这些基本操作的行为也不变。原型是一种对象行为的实现细节。 内省机制 js提供了便利的内省机制来检查对象的细节。Object.proto...
阅读全文
摘要:
ECMAScript标准库里配备了许多重要的类,如Array,function,以及Date等。扩展这些类生成子类可以方便完成很多工作,但它们的定义具有很多特殊的行为,所以很难写出行为正确的类。 Array示例 一个操作文件系统的库可能希望创建一个对象的目录,该目录继承了数组的所有行为。function Dir(path,entries){ this.path=path; for(var .
阅读全文
ECMAScript标准库里配备了许多重要的类,如Array,function,以及Date等。扩展这些类生成子类可以方便完成很多工作,但它们的定义具有很多特殊的行为,所以很难写出行为正确的类。 Array示例 一个操作文件系统的库可能希望创建一个对象的目录,该目录继承了数组的所有行为。function Dir(path,entries){ this.path=path; for(var .
阅读全文
摘要:
这个时候,首先调用Alien构造函数运行,创建一个空对象alien,把构造函数中的this绑定到alien上,然后运行Actor.call(alien,scene,0,0)产生了alien.id=++Actor.nextID,然后添加其它私有属性,但当又遇到id这个属性的时候,alien.id=++Alien.nextID,把上面从基类构造函数产生的id进行了修改。这个时候,id的属性就产生了歧义。
阅读全文
这个时候,首先调用Alien构造函数运行,创建一个空对象alien,把构造函数中的this绑定到alien上,然后运行Actor.call(alien,scene,0,0)产生了alien.id=++Actor.nextID,然后添加其它私有属性,但当又遇到id这个属性的时候,alien.id=++Alien.nextID,把上面从基类构造函数产生的id进行了修改。这个时候,id的属性就产生了歧义。
阅读全文
摘要:
当初始化SpaceShip原型时,我们尚未创建任何能作为第一个参数来传递的场景。并且SpaceShip的原型加入到场景的注册表中,而这绝不是我们想做的。这是一种使用子类时常用的方法。应当仅仅在子类构造函数中调用父类构造函数,而不是当创建子类原型时调用它。
一旦创建了SpaceShip的原型对象,我们就可以向其添加所有的可被实例共享的属性,包含一个用于在场景的图像数据表中检索的type名,以及一些太空飞船的特定方法。
阅读全文
当初始化SpaceShip原型时,我们尚未创建任何能作为第一个参数来传递的场景。并且SpaceShip的原型加入到场景的注册表中,而这绝不是我们想做的。这是一种使用子类时常用的方法。应当仅仅在子类构造函数中调用父类构造函数,而不是当创建子类原型时调用它。
一旦创建了SpaceShip的原型对象,我们就可以向其添加所有的可被实例共享的属性,包含一个用于在场景的图像数据表中检索的type名,以及一些太空飞船的特定方法。
阅读全文
摘要:
this变量是以不同的方式绑定的。每个函数都有一个this变量的隐式绑定。该this变量的绑定值是在调用该函数时确定的。对于一个词法作用域的变量,可以通过查找显式命名的绑定名来识别出其绑定的接收者。但this变量是隐式地绑定到最近的封闭函数。因此,对于CSVReader.prototype.read函数,this变量的绑定不同于传递给lines.map回调函数的this绑定。
阅读全文
this变量是以不同的方式绑定的。每个函数都有一个this变量的隐式绑定。该this变量的绑定值是在调用该函数时确定的。对于一个词法作用域的变量,可以通过查找显式命名的绑定名来识别出其绑定的接收者。但this变量是隐式地绑定到最近的封闭函数。因此,对于CSVReader.prototype.read函数,this变量的绑定不同于传递给lines.map回调函数的this绑定。
阅读全文
摘要:
共享有状态的数据可能会导致错误。通常在一个类的多个实例之间共享方法是安全的,因为方法通常是无状态的,这不同于通过this来引用实例状态。(因为方法调用的语法确保了this被绑定到实例对象,即使该方法是从原型中继承来的,共享方法仍然可以访问实例状态)一般情况下,任何不可变的数据可以被存储在原型中从而被安全地共享。有状态的数据原则上也可以存储在原型中,只要你真正想共享它。在原型中最常见的数据是方法,而每个实例的状态都存储在实例对象中。
阅读全文
共享有状态的数据可能会导致错误。通常在一个类的多个实例之间共享方法是安全的,因为方法通常是无状态的,这不同于通过this来引用实例状态。(因为方法调用的语法确保了this被绑定到实例对象,即使该方法是从原型中继承来的,共享方法仍然可以访问实例状态)一般情况下,任何不可变的数据可以被存储在原型中从而被安全地共享。有状态的数据原则上也可以存储在原型中,只要你真正想共享它。在原型中最常见的数据是方法,而每个实例的状态都存储在实例对象中。
阅读全文
摘要:
每个环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。在WEB浏览器中全局环境关联的是window对象。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
阅读全文
每个环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。在WEB浏览器中全局环境关联的是window对象。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
阅读全文
摘要:
将方法存储在原型中,使其可以被所有的实例使用,而不需要给每个实例对象增加额外的属性。
将方法存储在实例对象中会优化查找速度,当使用如u1.toString()方法,不需要搜索原型链来查找toString的实现。但,现代的js引擎深度优化了原型查找,所以将方法复制到实例对象并不一定保证速度有明显的提升。而且实例方法比起原型方法肯定会占用更多的内存。
阅读全文
将方法存储在原型中,使其可以被所有的实例使用,而不需要给每个实例对象增加额外的属性。
将方法存储在实例对象中会优化查找速度,当使用如u1.toString()方法,不需要搜索原型链来查找toString的实现。但,现代的js引擎深度优化了原型查找,所以将方法复制到实例对象并不一定保证速度有明显的提升。而且实例方法比起原型方法肯定会占用更多的内存。
阅读全文

浙公网安备 33010602011771号