JavaScript数据结构与算法原因
作为函数式编程语言,它非常适合用来学习数据结构和算法。通过它来学习数据结构比C、Java或Python这些标准语言更简单,学习新东西也会变得很有趣。
学习数据结构和算法十分重要。首要原因是数据结构和算法可以很高效地解决常见问题,这对你今后所写代码的质量至关重要(也包括性能;要是用了不恰当的数据结构或算法,很可能会产生性能问题)。其次,对于计算机科学,算法是最基础的概念。最后,如果你想入职最好的IT公司(如谷歌、亚马逊、微软、eBay等),数据结构和算法是面试问题的重头戏。
(作为最佳实践,我们会在关闭body标签前引入JavaScript代码。这样浏览器就会在加载脚本之前解析和显示HTML,有利于提升页面的性能。)
(第一种是alert('My text here'),将输出到浏览器的警示窗口;第二种是console.log('My text here'),将把文本输出到调试工具(谷歌开发者工具或是Firebug,根据你使用的浏览器而定)的Console标签页;第三种是通过document.write('My text here')直接输出到HTML页面里并用浏览器呈现。可以选择你喜欢的方式来调试。)
(作用域是指,在编写的算法函数中,我们能访问变量(在使用函数作用域时,也可以是一个函数)的地方。有局部变量和全局变量两种。)
JavaScript基础
1.变量
变量保存的数据可以在需要时设置、更新或提取。赋给变量的值都有对应的类型。JavaScript的类型有数、字符串、布尔值、函数和对象,还有undefined和null,以及数组、日期和正则表达式。
在强类型语言中,声明变量时需要指定变量的类型(例如,在Java中声明一个整型变量,要使用intnum = 1;)。如果需要在写JavaScript时对变量设定类型,也可以使用TypeScript。
虽然关键字var不是必需的,但最好每次声明一个新变量时都加上。可以声明一个变量并初始化成一个数值类型的值,然后把它更新成字符串或者其他类型的值,不过这并不是一个好做法。
通常,代码质量可以用全局变量和函数的数量来考量(数量越多越糟)。因此,尽可能避免使用全局变量。(为什么? 1.因为全局变量会占用更多的内存.(现在的计算机性能,可以忽略这个问题,除非是巨大的对象) 2.增加了代码的耦合性, 牵一发而动全身 ,不利于维护扩展和复用 3.虽然使用全局变量时,会提高性能, 但是,然并卵, 在耦合性以及维护性上, 这点性能优势不值一提.后期维护和耦合处理更重要.)
2.运算符
( &&和&都是表示与,区别是&&只要第一个条件不满足,后面条件就不再判断。 &和&&都可以用作逻辑与的运算符,&&为短路与,&不是短路与。另外&可以做为整数的位运算符)
根据标准,在JavaScript中有两种数据类型。 ❑ 原始数据类型:null、undefined、字符串、数、布尔值和Symbol[插图]。 ❑ 派生数据类型/对象:JavaScript对象,包括函数、数组和正则表达式。
JavaScript还支持delete运算符,可以删除对象里的属性。看看下面的代码。 var myObj = {name: 'John', age: 21}; delete myObj.age; console.log(myObj); // 输出对象{name: "John"} ( 因为 【数组】 本身也是一种特殊的对象 所以 delete 也是可以删除数组的。 比如 let arr = [1,2,3,4] 可以使用 delete arr[2] 删除数组 ★ 注意 。 delete 删除的时对应的内容, 也就是说 delete 和splice 这些数组方法不一样, delete 不会改变数组的长度, 而会返回empty 也就是 var array = [ 1 ,2 ,3 ,4 ]; delete array[2]; array; // 结果是 【1, 2,empty * 1 , 4 】 ; array.length , // 结果是 4)
3.真值和假值
4.相等运算符
使用==时,不同类型的值也可以被看作相等
toNumber和toPrimitive方法是内部的,
toNumber方法对不同类型返回的结果如下。
toPrimitive方法对不同类型返回的结果如下。
===运算符呢?简单多了。如果比较的两个值类型不同,比较的结果就是false。如果比较的两个值类型相同,结果会根据下表判断。
如果x和y类型不同,结果就是false。
用例子来验证一下表格中的结果。首先,我们知道下面的代码输出true(字符串长度大于1)。 console.log('packt' ? true : false); 那么下面这行代码的结果呢? console.log('packt' == true); 输出是false,为什么会这样呢? ❑ 首先,布尔值会被toNumber方法转成数,因此得到packt == 1。 ❑ 其次,用toNumber转换字符串值。因为字符串包含字母,所以会被转成NaN,表达式就变成了NaN == 1,结果就是false。 那么下面这行代码的结果呢? console.log('packt' == false); 输出也是false,为什么呢? ❑ 首先,布尔值会被toNumber方法转成数,因此得到packt == 0。 ❑ 其次,用toNumber转换字符串值。因为字符串包含字母,所以会被转成NaN,表达式就变成了NaN == 0,结果就是false。
5.控制结构
条件语句支持if...else和switch。循环支持while、do...while和for。
if...else语句也可以用三元运算符替换,例如下面的if...else语句。 if (num === 1) { num--; } else { num++; } 可以用三元运算符替换为: (num === 1) ? num-- : num++;
break会中止switch语句的执行。没有break会导致执行完当前的case后,继续执行下一个case,直到遇到break或switch执行结束。default关键字,在表达式不匹配前面任何一种情形的时候,就执行default中的代码(如果有对应的,就不会执行)。
var i = 0;
do {
console.log(i);
i++;
} while (i < 10);
区别是:在while循环里,先进行条件判断再执行循环体中的代码,而在do...while循环里,是先执行循环体中的代码再判断循环条件。do...while循环至少会让循环体中的代码执行一次。
var i = 0;
while (i < 10)
{
console.log(i);
i++;
}
6.函数
略,看懂了。
7.JavaScript面向对象编程
创建一个普通对象有两种方式。第一种方式是: var obj = new Object(); 第二种方式是: var obj = {}; 我们也可以这样创建一个完整的对象: obj = { name: { first: 'Gandalf', last: 'the Grey' }, address: 'Middle Earth' };
创建一个普通对象有两种方式。第一种方式是: var obj = new Object(); 第二种方式是: var obj = {}; 我们也可以这样创建一个完整的对象: obj = { name: { first: 'Gandalf', last: 'the Grey' }, address: 'Middle Earth' };
声明JavaScript对象时,键值对中的键就是对象的属性,值就是对应属性的值。在本书中,我们创建的所有的类,如Stack、Set、LinkedList、Dictionary、Tree、Graph等,都是JavaScript对象。
在面向对象编程(OOP)中,对象是类的实例。一个类定义了对象的特征。我们会创建很多类来表示算法和数据结构。例如我们如下声明一个类(构造函数)来表示书。
function Book(title, pages, isbn) {
this.title = title; this.pages = pages; this.isbn = isbn;
}
用下面的代码实例化这个类。
var book = new Book('title', 'pag', 'isbn');
然后,我们可以访问和修改对象的属性。 console.log(book.title); // 输出书名
book.title = 'new title'; // 修改书名
console.log(book.title); // 输出新的书名
类可以包含函数(通常也称为方法)。可以声明和使用函数/方法,如下所示。 Book.prototype.printTitle = function() { console.log(this.title); };
book.printTitle();
我们也可以直接在类的定义里声明函数。
function Book(title, pages, isbn) {
this.title = title; this.pages = pages; this.isbn = isbn;
this.printIsbn = function() { console.log(this.isbn); }; }
book.printIsbn();