学习JavaScript数据结构与算法

JavaScript基础

变量

  变量保存的数据可以在需要时设置、更新或提取。赋给变量的值都有对应的类型。JavaScript的类型有数字、字符串、布尔值、函数和对象。还有undefinednull,以及数组、日期和正则表达式。

注意JavaScript是弱类型语言,我们只需要使用varletconst去声明变量,而不必指定变量类型

在TypeScript中,我们可以在声明变量的时候指定变量的类型。很显然使用Typescript更加严谨,如Vue、React都已经开始全面拥抱Typescript了,或许在不久的将来,Typescript会成为前端编写的主流。但这并不是说JavaScript就没用了。 在之后的例子,我还是使用JavaScript

var num = 1; //{1}
num = 3; //{2}
const price = 1.5; //{3}
const name = 'mark_m'; //{4}
const trueValue = true; //{5}
const nullValue = null; //{6}
let und;

console.log("num:",typeof num,num);
console.log("price:",typeof price,price);
console.log("name:",typeof name,name);
console.log("trueValue:",typeof trueValue,trueValue);
console.log("nullValue:",typeof nullValue,nullValue);
console.log("und:",typeof und,nullValue);
  • 在第一行,展示了如何声明一个变量,虽然var不是必须的,但最好每次都加上。

注意:在申明变量时最好不要使用var,尽量使用const,少使用letvar声明的是一个变量,变量本身意味着结构可变,但凡结构可变的数据,其本身就意味着不稳定,也意味着代码设计本身存在的缺陷。

  • 在第二行,更新了已有变量。Js是弱类型语言,这就意味这可以把申明一个初始化类型为数字的值更新成其他类型的值,这很糟糕。

  • 在第三行,声明了一个十进制浮点数

  • 在第四行,声明了一个字符串

  • 在第五行,声明了布尔值

  • 在第六行,声明了null

  • 在第七行,声明了ubdefined

注意null表示变量没有值,undefined表示变量已经被声明,但尚未赋值。

变量作用域

  作用域指在编写的算法函数中,我们能访问的变量(在使用时,函数作用域也可以是一个函数)。有本地变量和全局变量两种。

  var myVariable = "global";
  myOtherVariable = "global";

  function myFunction() {
    var myVariable = "local";
    return myVariable;
  }

  function myOtherFunction() {
    myOtherVariable = "local";
    return myOtherVariable;
  }
  console.log(myVariable); //{1}
  console.log(myFunction()); //{2}
  console.log(myOtherVariable); //{3}
  console.log(myOtherFunction()); //{4}
  console.log(myOtherVariable); //{5}
  • 行1输出global,它是全局变量
  • 行2输出local,myVariable是在myFunction函数中声明的本地变量,所以作用域仅在myFunction内。
  • 行{3}输出global,引用了在第二行初始化了的全局变量myOtherVariable
  • 行{4}输出local。在myOtherFunction函数里,因为没有使
    var关键字修饰,所以这里引用的是全局变量myOtherVariable
    并将它赋值为local
  • 行{5}输出local(因为在myOtherFunction里修改了
    myOtherVariable的值)。

  代码质量可以用全局变量和函数的数量来考量(数量越多越
糟)。因此,尽可能避免使用全局变量。

操作符

  在JavaScript里有算数操作符、赋值操作符、比较操作符、逻辑操作符、位操作符、一元操作符和其他操作符。

  var num = 0; //{1}
  num = num + 2;
  num = num * 3;
  num = num / 2;
  num++;
  num--;
  num += 1; //{2}
  num -= 2;
  num *= 3;
  num /= 2;
  num %= 3;
  console.log("num == 1 : " + (num == 1)); // {3}
  console.log("num === 1 : " + (num === 1));
  console.log("num != 1 : " + (num != 1));
  console.log("num > 1 : " + (num > 1));
  console.log("num < 1 : " + (num < 1));
  console.log("num >= 1 : " + (num >= 1));
  console.log("num <= 1 : " + (num <= 1));
  console.log("true && false : " + (true && false)); // {4}
  console.log("true || false : " + (true || false));
  console.log("!true : " + !true);
  • 在行{1},我们用了算数操作符。在下面的表格里,列出了这些操作符
    及其描述。
算数操作符描述
+加法
-减法
*乘法
/除法
%取余
++递增
递减
  • 在行{2},我们使用了赋值操作符,在下面的表格里,列出了赋值操作
    符及其描述。
算数操作符描述
=赋值
+=加/赋值 (x += y) == (x = x + y)
-=减/赋值 (x -= y) == (x = x - y)
*=乘/赋值 (x *= y) == (x = x * y)
/=除/赋值 (x /= y) == (x = x / y)
%=取余/赋值 (x %= y) == (x = x % y)
  • 在行{3},我们使用了比较操作符。在下面的表格里,列出了比较操作
    符及其描述
算数操作符描述
==相等
===全等
!=不等
>大于
>=大于等于
<小于
<=小于等于
  • 在行{4},我们使用了逻辑操作符。在下面的表格里,列出了逻辑操作
    符及其描述。
算数操作符描述
&&
||
!

JavaScript也支持位操作符,如下所示

  console.log("5 & 1:", 5 & 1);
  console.log("5 | 1:", 5 | 1);
  console.log("~ 5:", ~5);
  console.log("5 ^ 1:", 5 ^ 1);
  console.log("5 << 1:", 5 << 1);
  console.log("5 >> 1:", 5 >> 1);

下面的表格对位操作符做了更详细的描述

算数操作符描述
&
~
^异或
<<左移
>>右移

typeof操作符可以返回变量或表达式的类型。我们看下面的代码:

  console.log("typeof num:", typeof num); // typeof num: number
  console.log("typeof Packt:", typeof "Packt"); // typeof Packt: string
  console.log("typeof true:", typeof true); // typeof true: boolean
  console.log("typeof [1,2,3]:", typeof [1, 2, 3]); // typeof [1,2,3]: object
  console.log("typeof {name:John}:", typeof { name: "John" }); // typeof {name:John}: object

JavaScript还支持delete操作符,可以删除对象里的属性。看看下面的
代码:

  var myObj = { name: "John", age: 21 };
  delete myObj.age;
  console.log(myObj); // 输出对象{name: "John"}

真值和假值

  在JavaScript中,true和false有些复杂。在大多数编程语言中,布尔值truefalse仅仅表示true/false。在JavaScript中,如"Packt"这样的字符串值,也可以看作true。

数值类型转换成布尔值
undefinedfalse
nullfalse
布尔值true是true,false是false
数字+0、-0和NaN都是false,其他都是true
字符串如果字符串是空的(长度是0)就是false,其他都是true
对象true

我们来看一些代码,用输出来验证上面的总结:

  function testTruthy(val) {
    return val ? console.log("truthy") : console.log("falsy");
  }
  testTruthy(true); //true
  testTruthy(false); //false
  testTruthy(new Boolean(false)); //true (对象始终为true)
  testTruthy(""); //false
  testTruthy("Packt"); //true
  testTruthy(new String("")); //true (对象始终为true)
  testTruthy(1); //true
  testTruthy(-1); //true
  testTruthy(NaN); //false
  testTruthy(new Number(NaN)); //true (对象始终为true)
  testTruthy({}); //true (对象始终为true)
  var obj = { name: "John" };
  testTruthy(obj); //true
  testTruthy(obj.name); //true
  testTruthy(obj.age); //false (年龄不存在)

相等操作符(=====

  当使用这两个相等操作符时,可能会引起一些困惑。
  使用==时,不同类型的值也可以被看作相等。这样的结果可能会使部分的JavaScript开发者感到困惑。用表格分析一下不同类型的值用相等操作符比较后的结果。

类型(x)类型(y)结果
nullundefinedtrue
undefinednulltrue
数字字符串x == toNumber(y)
字符串数字toNumber(x) == y
布尔值任何类型toNumber(x) == y
任何类型布尔值x == toNumber(y)
字符串或数字对象x == toPrimitive(y)
对象字符串或数字toPrimitive(x) == y

  如果xy是相同类型,JavaScript会比较它们的值或对象值。其他没有列在这个表格中的情况都会返回false

  toNumbertoPrimitive方法是内部的,并根据以下表格对其进行估值。

toNumber方法对不同类型返回的结果如下:

值类型结果
undefinedNaN
null+0
布尔值如果是true,返回1;如果是false,返回+0
数字数字对应的值
字符串将字符串解析成数字。如果字符串中包含字母,返回NaN;如 果是由数字字符组成的,转换成数字
对象Number(toPrimitive(vale))

toPrimitive方法对不同类型返回的结果如下:

值类型结果
对象如果对象的valueOf方法的结果是原始值,返回原始值。如果 对象的toString方法返回原始值,就返回这个值;其他情况 都返回一个错误

用例子来验证一下表格中的结果。首先,我们知道下面的代码输出
true(字符串长度大于1):

  console.log('packt' ? true : false); // true

那么这行代码的结果呢?

  console.log('packt' == true); // false

输出是false,为什么会这样呢?

  • 首先,布尔值会被toNumber方法转成数字,因此得到packt == 1
  • 其次,用 toNumber转换字符串值。因为字符串包含有字母,所以会被转成NaN,表达式就变成了NaN == 1,结果就是false

那么这行代码的结果呢?

console.log('packt' == false);

输出也是false。步骤如下所示。

  • 首先,布尔值会被toNumber方法转成数字,因此得到packt == 0
  • 其次,用toNumber转换字符串值。因为字符串包含有字母,所以会被转成NaN,表达式就变成了NaN == 0,结果就是false

那么===操作符呢?简单多了。如果比较的两个值类型不同,比较的结
果就是false。如果比较的两个值类型相同,结果会根据下表判断。

类型(x)结果
数字x 和 y 数值相同(但不是NaN)true
字符串x 和 y 是相同的字符true
布尔值x 和 y 都是true或falsetrue
对象x 和 y 引用同一个对象true

如果xy类型不同,结果就是false

我们来看一些例子:

  console.log("packt" === true); //false
  console.log("packt" === "packt"); //true
  var person1 = { name: "John" };
  var person2 = { name: "John" };
  console.log(person1 === person2); //false,不同的对象

控制结构

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值