JavaScript基础语法知识(二);

2-3-6 symbol 类型

ES5中包含5种原始类型:字符串、数字、布尔值、null和undefined。ES6引入了第6种原始类 型:symbol

ES5的对象属性名都是字符串,很容易造成属性名冲突。比如,使用了一个他人提供的对象,想 为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证 每个属性的名字都是独一无二的,这样就从根本上防止了属性名冲突。这就是ES6引入symb。l的 原因。

我们在讲解面向对象的时候再具体来讲解symbol类型。

2-3-7简单值和复杂值的区别(扩展)

至此,在JavaScript中除了 symbol以外的简单数据类型,就给大家介绍完了。还剩下一种复杂数 据类型,那就是对象,我们会在第6章进行详细的介绍。

这里要给大家扩展的一个知识点,那就是简单数据类型所创建的值被称之为简单值,而复杂数据 类型所创建的值被称之为复杂值。

那么简单值和复杂值具体有什么区别呢?下面我们一个一个来看:

1.简单值(或原始值)

简单值是表示JS中可用的数据或信息的最底层形式或最简单形式。简单类型的值被称为简单值, 是因为它们是不可细化的。

也就是说,数字是数字,字符是字符,布尔值是true或false, null和undefined就是null和 undefined。这些值本身很简单,不能够再进行拆分。由于简单值的数据大小是固定的,所以简 单值的数据是存储于内存中的栈区里面的。

let str = "Hello World";

let num = 10;

let bol = true;

let myNull = null;

let undef = undefined;

       
       


这里面就null和undefined比较特殊,打印出来的数据类型分别是object和undefined。因为 这两个数据类型没有对应的构造函数,当然什么是构造函数我们后面再说,现在我们只需要将 null和undefined看作是特殊的操作符来使用即可。

2.复杂值

在JavaScript中,对象就是一个复杂值。因为对象可以向下拆分,拆分成多个简单值或者复杂 值。复杂值在内存中的大小是未知的,因为复杂值可以包含任何值,而不是一个特定的已知值。 所以复杂值的数据都是存储于堆区里面。

//简单值

let str = "Hello World";

let num = 10;

let bol = true;

let myNull = null;

let undef = undefined;

//复杂值

let obj = {

name : 'xiejie', age : 18, isPassed : true

};

let arr = [1,2,3,"Hello",true];

  1. 1.    访问方式

按值访问

简单值是作为不可细化的值进行存储和使用的,引用它们会转移其值

let str = "Hello";

let str2 = str;

str = null;

console.log(str,str2);//null "Hello"

引用访问

复杂值是通过引用进行存储和操作的,而不是实际的值。创建一个包含复杂对象的变量时,其值 是内存中的一个引用地址。引用一个复杂对象时,使用它的名称(即变量或对象属性)通过内存中 的引用地址获取该对象值

let obj = {};

let obj2 = obj;

obj.name = "xiejie";

console.log(obj.name);//xiejie console.log(obj2.name);//xiejie

  1. 2.    比较方式

简单值采用值比较,而复杂值采用引用比较。复杂值只有在引用相同的对象(即有相同的地址)时 才相等。即使是包含相同对象的两个变量也彼此不相等,因为它们并不指向同一个对象

示例1:

let a = 10;

let b = 10;

let c = new Number(10);

let d = c;

console.log(a === b);//true

console.log(a === c);//false

console.log(a == c);//true

d = 10;

console.log(d == c);//true

console.log(d === c);//false

示例2:

let obj = {name : 'xiejie'};

let obj2 = {name : 'xiejie'};

console.log(obj == obj2);//false

console.log(obj === obj2);//false

let obj3 = {name : 'xiejie'};

let obj4 = obj3;

console.log(obj3 == obj4);//true

console.log(obj3 === obj4);//ture

5.动态属性

对于复杂值,可以为其添加属性和方法,也可以改变和删除其属性和方法;但简单值不可以添加 属性和方法

let str = 'test';

str.abc = true;

console.log(str.abc);//undefined

let obj = {};

obj.abc = true;

console.log(obj.abc);//true

复杂值支持动态对象属性,因为我们可以定义对象,然后创建引用,再更新对象,并且所有指向 该对象的变量都会获得更新。

—个新变量指向现有的复杂对象,并没有复制该对象。这就是复杂值有时被称为引用值的原因。 复杂值可以根据需求有任意多个引用,即使对象改变,它们也总是指向同一个对象

let obj = {name : 'xiejie'};

let obj2 = obj;

let obj3 = obj2;

obj.name = 'abc';

console.log(obj.name,obj2.name,obj3.name);

//abc abc abc

6.变量赋值

最后说一下关于变量的赋值,其实是可以分为直接赋值和引用赋值的。直接赋值,就是指将简单 值赋值给变量,而引用赋值是指将一个复杂值的引用赋值给变量,这个引用指向堆区实际存在的 数据。

直接赋值

let a = 3;

let b = a;

b = 5;

console.log(a);//3

引用赋值

let a = {value : 1};

let b = a;

b.value = 10;

console.log(a.value);//10

2-3-8类型转换

通过前面的介绍,我们已经知道了在JavaScript中有好几种不同的数据类型。然而这些数据类型 都是可以相互转换的。类型转换可以分为两种,隐性转换和强制转换。

1.隐性转换

当不同数据类型进行相互运算的时候,

当对非布尔类型的数据求布尔值的时候

预期为数字的时候:

算术运算的时候,我们的结果和运算的数都是数字,数据会转换为数字进行计算(-* / %)

类型

转换前

转换后

number

4

4

string

T

1

string

'abc'

NaN

string

0

boolean

true

1

boolean

false

0

undefined

undefined

NaN

null

null

0

预期为字符串的时候:

转为字符串使用+号时候,会自动转换为字符串 预期为布尔的时候:

转换为布尔值,undefined, null,                0, NaN转为false,其余转为true

2.强制转换

转换为数值 number() , parseInt() , parseFloat()转换函数

小技巧:

・转换字符串:a=""+数据

-转换布尔:!数据类型

-转换数值:数据类型*或/I

2-4运算符

任何编程语言基本上都离不开运算符。在JavaScript中也是支持众多运算符的。例如最常见的算 数运算符,比较运算符,逻辑运算符等。接下来,就让我们一起来看一下JavaScript中这几种常 见的运算符。

2-4-1算数运算符

常见的算数运算符有加减乘除和取模运算。主要需要注意的就是,在动态语言中做除法运算时, 能够得到小数。下面是关于算数运算符的示例:

console.log(5 + 3.14);//8.14

console.log(6 - 11);//-5

console.log(7 * 3);//21

console.log(5 / 2);//2.5

console.log(10 % 3);//1

从ES6开始新增加了求富运算,使用两个*号代表求富。以此可以代替以前的Math.pow()方法

console.log(2 ** 3);//8

2-4-2 一元运算符

所谓一元运算符,就是指只作用于一个操作数的运算符。常见的一元运算符有两种,赋值运算符 和递增递减运算符。

  1. 1.    赋值运算符

关于赋值运算符,前面我们已经见到过了。最常见的就是=,代表将右边的内容赋值给左边。除 此之外,还有+=、-=、*=等一系列赋值运算符,具体的示例如下:

let a = 5;

a += 5;

console.log(a); // 10

a -= 3;

console.log(a); // 7

a *= 5;

console.log(a); // 35

a /= 5;

console.log(a); // 7

a %= 2;

console.log(a); // 1

2.递增和递减

除了上面所介绍的赋值运算符以外,常见的一元运算符还有递增和递减。在递增递减中,主要需 要注意前置和后置的区别。如果是前置,那么是先自增或自减,然后参与运算。如果是后置,则 是先参与运算,然后再自增或者自减,示例如下:

前置示例:

let a = 2;

let b = 10;

let c = 一a + b;

let d = a + b;

console.log(a,b,c,d);//1 10 11 11

后置示例:

let a = 2;

let b = 10;

let c = a一 + b;

let d = a + b;

console.log(a,b,c,d);//1 10 12 11

需要注意的是,我们的自增自减操作符不仅仅局限于数值,其他类型也可以,遵循下面的规则:

・在应用于一个包含有效数字字符的字符串时,现将其转换为数字值,再执行加减1操作。字 符串变量变为了数值变量。

-在应用于一个不包含有效数字字符的字符串时,将变量的值设置为NaN,字符串变量变成数 值变量。

-遇布尔值false时,先将其转换为0再执行加减1操作,布尔值变量变成数值变量。

-遇布尔值true时,先将其转换为1再执行加减1操作,布尔值变量变成数值变量。

・在应用浮点数数值时,执行加减1操作。

示例:

let si = "123";

let s2 = "123Hello";

let s3 = "Hello";

let s4 = true;

let s5 = 3.14;

console.log(一s1);//122 console.log(一s2);//NaN console.log(一s3);//NaN console.log(一s4);//0 console.log(一s5);//2.14

2-4-3比较运算符

1.关系运算符

小于,大于,小于等于,大于等于 数的比较就不用说了,如下:

console.log(5 > 3);//true console.log(3 > 5);//false

主要说一下字符串的比较,如下:

console.log("c" > "b");//true console.log("c" > "box");//true

这里的比较主要是按照ASCII码来进行比较的。

如果是一个字符串和一个数字进行比较,那么会将字符串先转换为数字,如果不能转换为数字, 则转换为NaN

console.log("5" > 3);//true,因为''5"转为了5

//任何一个数与NaN进行关系比较,返回的都是false

console.log("Hello" > 3);//false,因为"Hello"转为了NaN

完整的特殊规则如下:

则比较两个字符串对应的字符编码

则将另一个操作数转换为一个数值,然后执行数值的比较 则调用这个对象的valueOf()方法,用得到的结果按照前面的规

贝U执行比较。如果对象没有valueOf()方法,则调用toString()方法,并用得到的结果 根据前面的规则执行比较。

•如果一个数是布尔值,则先将其转换为数值,然后再进行比较

还需要注意,任何数和NaN进行比较返回的都是false

console.log(10 > NaN);//false console.log(10 < NaN);//false

  1. 2.    相等和不相等

==表示相等,!=表示不相等,数据类型不同的数据进行相等比较的话会自动转换数据类型, 还有一些其他的转换规则如下:

• null和undefined是相等的

•如果有一^操作数是NaN,则返回false, NaN和NaN比较也是false

-如果是数字的字符串和数字进行比较,会先将字符串转换为数字

•布尔值里面true转换为1, false转换为0

下表列出了一些特殊的情况

表达式          值

null == undefined          true

"NaN" == NaN              false

5 == NaN                      false

NaN == NaN                false

NaN != NaN                   true

false == 0                        true

true == 1                         true

true == 2                       false

undefined == 0             false

null == 0                        false

"5" == 5                           true

  1. 3.    全等和不全等

全等是===,不全等是!==这个就是必须数据类型和数值都相等,如下:

2-4-4逻辑运算符

  1. 1.   

所谓非,就是取反,非真即假,非假即真

let i = true;

console.log(!i);//false

非运算符不仅仅只能用于布尔值,其他数据类型也是可以的,如下:

•如果操作数是一个对象,返回false

•如果操作数是一个空字符串,返回true

•如果操作数是一个非空字符串,返回false

•如果操作数是数值0,返回true

•如果操作数是任意非0数值(包括Infinity),返回false

•如果操作数是null,返回true

•如果操作数是NaN,返回true

•如果操作数是undefined,返回true

console.log(!false);//true console.log(!"blue");//false console.log(!0);//true console.log(!NaN);//true console.log(!"");//true console.log(!12);//false

可使用双否定!!来判定一个值是真值还是假值,如下:

console.log(!!'');//false console.log(!!NaN);//false console.log(!!'Hello');//true

  1. 2.   

作用于两到多个值,并且只有所有的操作数都是真值时,才为true

JavaScript里面的与存在短路现象,具体说明如下:

・第一个操作数为真:会进入第二个操作数的判断,且无论第二个操作数真假,都会返回第二 个操作数。

•第一个操作数为假:不会进入第二个操作数的判断,直接返回第一个操作数。

来看下面的例子:

console.log(3 && 5);//5 console.log("Hello" && 20);//20 console.log("Hello" && false);//false console.log("" && "shoe");//"" console.log("Hello" && '');//''

下面是关于与运算符的一道经典练习题:

let a = true;

let b = a && c;//因为atrue,所以会判断第2个数

console.log(b);

//ReferenceError: c is not defined

let a = false;

let b = a && c;//因为afalse,所以不会判断第2个数

console.log(b);//false

如果你看《JavaScript高级程序设计》这本书,里面还讲了诸如下面这些杂七杂八的规则:

-如果第一个操作数是对象,则返回第二个操作数

•如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对 象

-如果两个操作数都是对象,则返回第二个操作数

•如果有一个操作数是null,则返回null

•如果有一个操作数是NaN,则返回NaN

•如果有一^操作数是undefined,则返回undefined

console.log(3 && 5);//5

console.log(NaN && NaN);//NaN

console.log(null && null);//null console.log(undefined && undefined);//undefined

但是这些规则大多都是可以使用短路现象来解释的,所以不需要你去记,大致了解即可。

3.

同样是作用于两到多个值,但是只要有一个操作数为真,就返回真

console.log(false || true);//true console.log(true || false);//true

JavaScript里面的或同样存在短路现象,具体说明如下:

・如果第一个操作数为真,则不会进入第二个数的判断。所以无论第二个操作数真假,都直接 返回第一个操作数

•如果第一个操作数为假,则会进入第二个数的判断。但是无论第二个操作数真假,都直接返 回第二个操作数

来看下面的例子:

console.log(false || true);//true console.log("Hello" || "");//Hello console.log("Hello" || "str");//Hello console.log(NaN || "");//"" console.log(0 || "Hello World");//Hello World console.log(11 || 'str');//str console.log(11 || false);//false

下面是关于或运算符的一道经典练习题:

let a = false;

let b = a || c;//因为afalse,所以会判断第2个数console.log(b);

//ReferenceError: c is not defined

let a = true;

let b = a || c;//因为afalse,所以会判断第2个数console.log(b);//true

如果你看《JavaScript高级程序设计》这本书,里面也讲了诸如下面这些杂七杂八的规则:

-如果第一个操作数是对象,则返回第一个操作数

•如果第一个操作数的求值结果为false,则返回第二个操作数

-如果两个操作数都是对象,则返回第一个操作数

•如果两个数都是null,则返回null

•如果两个数都是NaN,则返回NaN

•如果两个数都是undefined,则返回undefined

console.log(3 || 5);//3 console.log(NaN || NaN);//NaN

console.log(null || null);//null console.log(undefined || undefined);//undefined

不过这些规则大多也都是可以使用短路现象来解释的,所以根本不需要你去记,大致了解即可。

2-4-5位运算符(扩展)

按位运算符是将操作数换算成32位的二进制整数,然后按每一位来进行运输。例如:

・5 的 32 位为 00000000000000000000000000000101

・100 的 32 位为 00000000000000000000000001100100

・15 的 32 位为 00000000000000000000000000001111

  1. 1.    按位非

按位非运算符~会把数字转为32位二进制整数,然后反转每一位

所有的1变为0,所有的0变为1

5 的 32 位为 00000000000000000000000000000101

〜5: 11111111111111111111111111111010 转换出来就为-6

按位非,实质上是对操作数求负,然后减去1

  1. 2.    按位与

按位或运算符&会把两个数字转为32位二进制整数,并对两个数的每一位执行按位与运算

第一个数字第二个数字结果

1                          1                          1

0                          0                          0

具体示例:

console.log(12 & 10);//8

12的32位二进制表示为:1100

10的32位二进制表示为:1010

结果为:1000

3.按位或

按位或运算符|会把两个数字转为32位二进制整数,并对两个数的每一位执行按位或运算

第一个数字

第二个数字

结果

1

1

1

1

0

1

0

1

1

0

0

0

具体示例:

console.log(12 | 10);//14

12的32位二进制表示为:1100

10的32位二进制表示为:1010

结果为:1110

  1. 4.    按位异或

按位或运算符人会把两个数字转为32位二进制整数,并对两个数的每一位执行按位异或运算, 两位不同返回1,两位相同返回0

第一个数字第二个数字结果

1                         0                            1

0                         1                            1

0                         0                            0

具体示例:

console.log(12 人 10);//6

12的32位二进制表示为:1100

10的32位二进制表示为:1010

结果为:0110

按位异或如果是非整数值,如果两个操作数中只有一个为真,就返回1,如果两个操作数都是 真,或者都是假,就返回0

console.log(true 人"Hello");//1

console.log(false 人"Hello");//

console.log(true 人 true);//0

console.log("Hello"人"Hello");//0

console.log(false 人 false);//0

console.log(true 人 false);//1

注意这里的Hello被转换为了 NaN

  1. 5.    按位移位

按位移位运算符VV和 >> 会将所有位向左或者向右移动指定的数量,实际上就是高效率地将数 字乘以或者除以2的指定数的次方

<< :乘以2的指定数次方

console.log(2«2);//8

2乘以2的2次方

00000010转换为 00001000

>> :除以2的指定数次方

16除以2的1次方

00010000转换为 00001000

猜你喜欢

转载自www.cnblogs.com/13330893721zhy/p/11376431.html