深入理解 JavaScript 中的 delete 操作符

delete 操作符用于删除对象的属性。

似乎很多同学(包括我)对 delete 操作符都是似是而非,为什么有的属性可以被删除,有的却不能被删除?为什么能够删除对象的属性却不能删除变量或函数?在 eval 和 严格模式下,delete 操作符又有哪些特性?等等。。

本文将从基本概念到 ECMPScript 内部原理来学习 delete 操作符。

语法

表达式

1
2
delete object.property // 点操作符方式,常用方式
delete object['property'] // 字符串属性名方式

参数

  • object - 对象名称,或者返回一个对象的表达式
  • property - 将要删除的属性

返回值

delete 操作符返回 true 或 false。当被 delete 的对象的属性存在并且拥有 DontDelete (对象属性的一个内部属性,拥有该内部属性表明该属性不能被删除) 时返回 false(在严格模式下将抛出异常),否则返回 true。需要注意的是,对象属性不存在时也返回 true,所以返回值并非完全等同于删除成功与否

【译】构建您自己的 AngularJS,第一部分:scopes 和 digest

原文链接:Make Your Own AngularJS, Part 1: Scopes And Digest

AngularJS

Angular 是一个成熟和功能强大的 JavaScript 框架,也是一个庞大的框架,要正真有效地使用它,需要掌握许多新概念。在 Web 开发人员涌向 Angular 的同时,许多人都面临着同样的疑问:Digest 到底是做什么的?可以有哪些不同的方式来定义一个指令(directive)?service 和 provider 之间有些什么区别?

Angular官方文档是非常好的学习资源,并且还有越来越多的第三方资源,不过,想要深入了解一个新的框架,没有比分解它,然后研究其内部运作原理更加有效。

在本系列文章中,我将从零开始建立一个 AngularJS 类库,并逐步深入讲解,最后,您将对 Angular 的工作原理有一个全面深刻地理解。

这是本系列的第一部分,我们将分析 Angular 中的 scopes 的工作原理,并且将知道像 $eval$digest$apply 这些方法到底有些什么作用,Angular 的脏值检查(dirty-checking)貌似很神奇,但是后面您将看到的并非如此。

常见排序算法【归档】

最近整理了一些常见的排序算法,资料基本上都来自网上,大部分参考了维基百科,分析了常见算法的原理,并举例分步说明,有的还给出了排序动画演示,但没有涉及算法复杂度等方面的概念,最后对每一种排序算法都给出了至少一种 JavaScript 的实现方法(因为我是做前端方面的,所以只给出了 JavaScript 代码)。

由于自己能力和经验有限,难免出现某些纰漏和错误,欢迎指正。

日本程序员 norahiko,写了一个排序算法的动画演示,非常有趣。另外,今天一同事告诉我有一个排序算法的舞蹈,请点击【程序员的艺术:排序算法舞蹈】。

常见排序算法 - 基数排序 (Radix Sort)

算法原理

基数排序 (Radix Sort) 是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。基数排序的发明可以追溯到 1887 年赫尔曼·何乐礼打孔卡片制表机 (Tabulation Machine)上的贡献。

排序过程:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

基数排序法会使用到桶 (Bucket),顾名思义,通过将要比较的位(个位、十位、百位…),将要排序的元素分配至 0~9 个桶中,借以达到排序的作用,在某些时候,基数排序法的效率高于其它的比较性排序法。

Data Structure Visualizations 提供了一个基数排序的分步动画演示。

常见排序算法 - 桶排序 (Bucket Sort)

算法原理

桶排序 (Bucket sort)或所谓的箱排序的原理是将数组分到有限数量的桶子里,然后对每个桶子再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序),最后将各个桶中的数据有序的合并起来。

排序过程:

  1. 假设待排序的一组数统一的分布在一个范围中,并将这一范围划分成几个子范围,也就是桶
  2. 将待排序的一组数,分档规入这些子桶,并将桶中的数据进行排序
  3. 将各个桶中的数据有序的合并起来

Data Structure Visualizations 提供了一个桶排序的分步动画演示。

常见排序算法 - 猴子排序 (Bogo Sort)

算法原理

猴子排序 (Bogo Sort) 是个既不实用又原始的排序算法,其原理等同将一堆卡片抛起,落在桌上后检查卡片是否已整齐排列好,若非就再抛一次。其名字源自 Quantum bogodynamics,又称 bozo sort、blort sort 或猴子排序(参见无限猴子定理)。并且在最坏的情况下所需时间是无限的。

伪代码:

1
2
3
while not InOrder(list) do
Shuffle(list)
done

常见排序算法 - 鸡尾酒排序 (Cocktail Sort/Shaker Sort)

算法原理

为什么叫鸡尾酒排序?其实我也不知道,知道的小伙伴请告诉我。

其实它还有很多奇怪的名称,比如双向冒泡排序 (Bidirectional Bubble Sort)、波浪排序 (Ripple Sort)、摇曳排序 (Shuffle Sort)、飞梭排序 (Shuttle Sort) 和欢乐时光排序 (Happy Hour Sort)。本文中就以鸡尾酒排序来称呼它。

鸡尾酒排序是冒泡排序的轻微变形。不同的地方在于,鸡尾酒排序是从低到高然后从高到低来回排序,而冒泡排序则仅从低到高去比较序列里的每个元素。他可比冒泡排序的效率稍微好一点,原因是冒泡排序只从一个方向进行比对(由低到高),每次循环只移动一个项目。

以序列(2,3,4,5,1)为例,鸡尾酒排序只需要访问一次序列就可以完成排序,但如果使用冒泡排序则需要四次。但是在乱数序列状态下,鸡尾酒排序与冒泡排序的效率都很差劲,优点只有原理简单这一点。

排序过程:

  1. 先对数组从左到右进行冒泡排序(升序),则最大的元素去到最右端
  2. 再对数组从右到左进行冒泡排序(降序),则最小的元素去到最左端
  3. 以此类推,依次改变冒泡的方向,并不断缩小未排序元素的范围,直到最后一个元素结束

图片来自维基百科

常见排序算法 - 归并排序 (Merge Sort)

算法原理

归并排序(Merge Sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

归并操作(Merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。归并排序有多路归并排序、两路归并排序 , 可用于内排序,也可以用于外排序。这里仅对内排序的两路归并方法进行讨论。

算法思路:

  1. 把 n 个记录看成 n 个长度为 l 的有序子表
  2. 进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表
  3. 重复第 2 步直到所有记录归并成一个长度为 n 的有序表为止。

图片来自维基百科

常见排序算法 - 希尔排序 (Shell Sort)

算法原理

希尔排序算法是按其设计者希尔(Donald Shell)的名字命名,该算法由1959年公布,是插入排序的一种更高效的改进版本。它的作法不是每次一个元素挨一个元素的比较。而是初期选用大跨步(增量较大)间隔比较,使记录跳跃式接近它的排序位置;然后增量缩小;最后增量为 1 ,这样记录移动次数大大减少,提高了排序效率。希尔排序对增量序列的选择没有严格规定。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
  • 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位

算法思路:

  1. 先取一个正整数 d1(d1 < n),把全部记录分成 d1 个组,所有距离为 d1 的倍数的记录看成一组,然后在各组内进行插入排序
  2. 然后取 d2(d2 < d1)
  3. 重复上述分组和排序操作;直到取 di = 1(i >= 1) 位置,即所有记录成为一个组,最后对这个组进行插入排序。一般选 d1 约为 n/2,d2 为 d1 /2, d3 为 d2/2 ,…, di = 1。

图片来自维基百科

常见排序算法 - 插入排序 (Insertion Sort)

算法原理

设有一组关键字{K1, K2,…, Kn};排序开始就认为 K1 是一个有序序列;让 K2 插入上述表长为 1 的有序序列,使之成为一个表长为 2 的有序序列;然后让 K3 插入上述表长为 2 的有序序列,使之成为一个表长为 3 的有序序列;依次类推,最后让 Kn 插入上述表长为 n-1 的有序序列,得一个表长为 n 的有序序列。

具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤 2~5

如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序

二分查找法,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

图片来自维基百科

go2top