JavaScript - JS基础

31 阅读8分钟
1、关于文档
2、语法,
3、关键字 保留字,
4、变量,
5、数据类型,
6、操作符,
7、语句,
8、函数
9、***JS第一道难关:类型转换(隐式转换)***

1、关于文档

  1. <script type="text/javascript" src="###" async defer />

    async 异步下载脚本。

    defer 延迟加载脚本文件,表示等文档完全解析和显示之后再运行脚本。

  2. doctype 文档类型

    混杂模式(quirks mode,不推荐)、标准模式(standards mode)

2、语法

区分大小写、标识符、语句、注释、严格模式(use strict)。

3、关键字、保留字

4、变量(var、let、const)

  1. var message; // 正确,但不推荐。 message 为 undefined。
  2. var message = "hi"; message = 100; //正确,但不推荐
  3. var message = "hi"; var message = 100; // 正确,但不推荐。第二个var会自动被忽略
  4. var message = "hi", title = 100; //正确,但不推荐
  5. function test () { msg: 'hi'; } // 正确,但不推荐。此时msg为全局变量。
  6. var a = b = c = d = 10; // 正确,但不推荐
// var a = b = c = d = 10; 等同于
var d;
var c;
var b;
var a;
d = 10;
c = d;
b = c;
a = b;
  1. var 的变量声明提升
console(x); // undefined
var x = 10; // 变量声明提升 + x = 10
console(x); // 10
x = 20;     // x = 20
console(x); // 20
// 上面的代码会发生变量声明提升
// 变量声明提升后为
var x;
console.log(x);
x = 10;
console.log(x);
x = 20;
console.log(x);

5. 数据类型

Undefined, Null, Boolean, Number, String, Object, Symbol

typeof ...
"undefined","boolean","number","string","object", "function"

instanceof...
// 判断数据是否为某个对象的实例,返回布尔值
// 无法判断基础类型

Object.prototype.toString.call(**)
// 对于判断一个数据的数据类型我们开发时应该用 Object.prototype.toString.call(**)
// 判断结果更精确,范围更广:
// "[object Undefined]", "[object Null]",
// "[object Boolean]","[object Number]","[object String]",
// "[object Object]"
// 能够区分原生引用类型
// "[object Function]","[object Array]","[object Date]", "[object RegExp]"
// 不能判断自定义引用类型的构造类,即不能判断自定义对象类型

// 关于检测数据类型是否为 数组,使用Array.isArray()更加简便实用,推荐。
  1. Undefined, Null

    在JavaScript中,UndefinedNull而生,Null没有Undefined重要。

// Undefined
var message;
console.log(message);  //undefined
console.log(title);   //报错
alert(message);      //undefined
alert(title);       // 报错
alert(typeof message);  // undefined
alert(typeof title);   //  undefined

//Null   表示为空
// 在JS中 null既是对象,也不是对象,史称【薛定谔的对象】
  1. Boolean
Boolean()falsetrue
Undefinedundefinedn/a(指不适用)
Booleanfalsetrue
Number0、NaN非0,非NaN数字
String""(空字符串)非空字符串
Objectnull非null对象
  1. Number
// 1. -Infinity,Number.MIN_VALUE...-0, +0...Number.MAX_VALUE,Infinity
// 2. 0.1 + 0.2 != 0.3 (54位2进制,第一位符号位,2-12位指数,13-64有效数字)
// 3. parseInt(ag1, ag2) 第二个参数为ag1的进制(10进制:默认;8进制:第一位需0开头 严格模式报错;16进制:第一位需0x), Number()指定第二个参数无效。
//    ES5之后,parseInt()默认按10进制解析,会自动解析8进制(即parseInt("070")解析为70),0x会按照16进制解析(即parseInt("0xF")将解析为15)
// 4. parseFloat(ag1, ag2)
// 5. Number()  推荐, Number(null)  0 , Number(undefined)  NaN
parseInt("1.33.33.33"); // 1        脏数据
parseFloat("1.33.33.33"); // 1.33   脏数据
Number("1.33.33.33") // NaN         推荐
  1. String
// 1. ES中的字符串不可变的。也就是说字符串一旦创建,它们的值就不会发生改变。
// 2. 转义序列(非打印字符)
\n, \r, \t, \b, \f(换行,回车,制表,推格,进纸)
\\, \', \", \xnn, \unnnn (斜杠 \,单引号 ', 双引号 ", 十六进制码nn表示一个字符, 十六进制码nnnn表示一个Unicode字符)

// 3. toString() 一般不传参,传递一个参数表示转换为对应参数的进制:2、8、10、16 的字符串 "230"
toString()String()
Undefined报错"undefined"
Null报错"null"
Boolean十进制表示数值的字符串十进制表示数值的字符串
Number。。。。。。
String。。。。。。
Object。。。。。。
  1. Object
// Object类型 是所有它的实例对象的基础,
constructor(); // 构造函数,用于创建对象实例
hasOwnProperty(propName); // 检测某项属性是否位于对象实例上,非原型上
isPrototypeOf(obj); // 传入的obj 是否为当前对象的原型
propertyIsEmmerable(propName); // 检测传入的某项属性是否能够通过for-in枚举出来
toString()
toLocaleString()
valueOf()
  1. Symbol

6. 操作符

一元,位,布尔 | 乘性,加性 | 相等,关系,条件 | 赋值,逗号
  1. 一元操作符:+ - ++ --
// + - 置于 常量数据 之前,即为一元操作符。此时会对后接数据进行Number()转化。
+false; // 0
-false; // -0

// ++ -- 操作 变量,会对数字型变量进行自增或自减操作,非数字型则会执行Number()操作转换
// 不论x放在 ++ -- 前面或后面,x的值都会变换,而整体表达式的值则不同。
// x++ 整体表达式的值为 x自增前的值,++x整体表达式为x自增后的值。
var x = false;
var y = x++; // y===0, x===1
var z = ++x; // z===2; x===2
  1. 位操作符:& | ~ ^ << >> >>>
// 按位与: &, 二进制码 按与结合。0 + 0 = 0、0 + 1 = 0、1 + 1 = 1

// 按位或:|, 二进制码 按或结合。0 + 0 = 0、0 + 1 = 1、1 + 1 = 1

// 按位非:~, 二进制码 按非转换。~n (-n-1: 负值减一, 向下取整), ~~n (向下取整) 
~~3.22; // 3, ~~ 正数向下取整
~~-3.22; // -3, ~~ 负数向上取整

// 按位异或: ^, 二进制码 按异或结合。 0 ^ 0 = 0、0 ^ 1 = 1、1 ^ 1 = 0
a = 1; b = 2;
a ^= b; b ^= a; a ^=b; // a, b值交换

// 左移: <<, n << m, n * ( 2 的 m 次方)

// 右移: >>, n >> m, n / ( 2 的 m 次方)    会向下取整
9 >> 2; // 2, 向下取整
-9 >> 2; // -3, 向下取整

// 无符号右移: >>>, n >>> m, n / ( 2 的 m 次方)    向下取整,n为负数表现杂乱
-3 >>> 1; // 2147483646
  1. 布尔操作符:&& || !
// 与, 或, 非
// JS有短路操作
// 即&&,前值为真,进行下一个值计算,整个判断语句的值为第二个值。
// 前值为假,不进行下一个值计算,整个判断语句的值为第一个值;

// || 操作符 类似于 &&,逻辑相反。
// 即&&,前值为假,进行下一个值计算,整个判断语句的值为第二个值。
// 前值为真,不进行下一个值计算,整个判断语句的值为第一个值;
  1. 乘性操作符:* / %
// % 求取余数。
5 % 2; // 1
  1. 加性操作符:+ -
// 置于两个 常量数据 之间时,为加性操作符。
  1. 相等操作符:== === != !==
// ==, != 会对前后对比数据进行数据类型转换。
// ===, !== 不会转换,必须数据类型相同,并且值相同。
undefined == null; // true
undefined === null// false
  1. 关系操作符:< > <= >=
"23" < "3"; // true, 均为字符串,比较字符串字符编码
"23" < 3;   // false, "23"转化为数字
"a" < 3;    // false, "a"转换为NaN
  1. 条件操作符:*** ? ** : **
  2. 赋值操作符:= *= /= %= += -=
  3. 逗号操作符:num = (1,2,3,4,5) // num = 5

运算符优先级

  1. ()
  2. ++ -- |
  3. * /, 后+ -
  4. > < >= <=
  5. == !== === !==
  6. &&, 后||
  7. 赋值运算符
  8. 默认从左到右,除了赋值与三目运算符及指数运算

7. 语句

for(ag1; ag2; ag3) { ag4 }
for(var i = 0; i < count; i++){}
// 执行顺序
// ag1
// ag2 - ag4 - ag3
// ag2 - ag4 - ag3
// ag2 - ag4 - ag3

8. 函数

  • 参数 arguments
      1. ECMAScript 函数内部使用一个数组来接收的。所以在使用函数时,传递参数与否,传递几个参数,都是无所谓的。(没有传递的参数会默认为undefined
      1. 函数内部用来接收传入参数的数组可以用arguments对象访问。
    function example( name, age) {}
    // arguments[0]可以访问到运行example函数时接受到的第一个参数;
    // arguments[1]可以访问到运行example函数时接受到的第二个参数;
    // 并且可以使用 arguments[0] + age这种组合方式,操作
    // arguments[0] 和 函数的第一个参数(即name)变化同步,但他们并不是访问的同一个地址的变量
    // arguments[n]的方式最好只是读取,改写操作在非严格模式下可以,并且变化同步name、age。但在严格模式下非但不能改变name、age的值,并且会报错。
    
      1. arguments.length值为运行时的值,即其结果不由定义函数时参数个数决定,而是运行时传递的参数数量决定。
  • 没有重载
    • 由于前面参数由一个数值所承接,所有函数没有重载。
    • 如果在ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数。

9. 类型转换(隐式转换)

类型转换,就是转换数据类型

Undefined Null Boolean Number String Object Symbol

(一)显式数据类型转换(工作中推荐使用方式)

  1. Boolean()
  2. parseInt(ag1, ag2) parseFloat(ag1, ag2) Number()
  3. toString(10) String()

这个三点转换方式,在前面的数据类型小结里面已经有描述。

(二)隐式数据类型转换(利用操作符进行转换)

学习隐式转换是为了在工作中避免

1. 一元:+ - ++ --,会先隐式对数据进行Number()操作,再进行++ --操作。

-false; // -0
-true; // -1
-""; // -0
-"dafsdf"; // NaN
- {}; // NaN
-[-1]; // 1
-[-1, ]; // 1, IE为undefined
-[-1,-2]; // NaN

+null; // 0
++null; // 报错
var x = null; ++x; // 1

2. 位:& | ~ ^ << >> >>>,会先隐式对数据进行Number()操作,再进行相应操作。

// 虽然会隐式对数据进行Number()操作,但是这里暂时认为的-NaN为0,而非NaN,背后真实的原因,我也不是很清楚
~undefined; // -1
~NaN; // -1
// << >> >>> 同上

3. 布尔:&& || !,会对前后两个进行布尔转换。但最后的值不是布尔值,而是对应表达式的值(将布尔操作符时有描述)

左 && 右; // Boolean(左) && Boolean(右)。
1 && null; // null
!!1; // true

4. 乘性 * / %, 乘性操作符,会隐式对前后数据进行Number(),然后再执行操作

5. 加性 + -, 基本原则是对数据进行隐式Number()操作,然后执行操作。但+有些特殊。

// - 操作符,对前后两个数据进行隐式的Number()转换,然后执行操作
// + 操作符,对前后两个数据进行隐式的Number()转换,然后执行操作
// ******* 当+操作符,前后某个数据都是字符串时,执行拼接操作 *******
// ******* 当+操作符,前后某个数据都是对象时,执行拼接操作 *******
"22" + undefined; // "22undefined"
"22" + null; // "22null"
"22" + false; // "22false"
"22" + true; // "22true"
"22" + 33; // "2233"
"22" + {a: "asdf"}; // "22[object Object]"
"22" + [1,2,4]; // "221,2,4"
"22" + function A(){return "33";}; // '22function A(){return "33";}'
"22" + new Date(); // '22Thu Mar 23 2023 09:11:55 GMT+0800 (中国标准时间)'

6. 条件:*** ? ** : **

const val = 1`value is ${val != '0'}` ? 'defined' : 'undefined'; // defined

7. 关系:> < >= <=

总是转换为Number进行比较,若均为字符串,则比较字符的Unicode码值。

// 特例
null >= 0; //true
null == 0; // false

8. 相等:== === != !==

JS的怪异之处:

A == B ≠> A >= B。因为最初设计思想是 a > ba >= b一组,a==b与其他运算符一组(如a != b,a !== b)。

关系运算符和相等运算符并不是一个类别的。

关系运算符,在设计上,总是尝试转为一个Number

相等运算符没有这方面的考量。

9. 赋值:=

  1. 复制变量值:复制值 与 复制引用指针。
  2. 传递参数: 值传递 与 引用传递。

10. 逗号: let a = (1,2,3,4)