通俗重制系列--JavaScript知识点

简介: 通俗重制系列--JavaScript知识点

通俗重制系列--JavaScript知识点


基本语法

条件语句

JavaScript 提供if结构和switch结构,完成条件判断,即只有满足预设的条件,才会执行相应的语句。

if结构

1.规则

  • 先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。
  • 所谓布尔值,指的是 JavaScript 的两个特殊值,true表示真,false表示伪。
  • 如果表达式的求值结果为true,就执行紧跟在后面的语句;如果结果为false,则跳过紧跟在后面的语句。

2.基本形式

if (布尔值){
  语句
}
// 或者
if (布尔值) 语句;

3.关于 =

  • 赋值表达式(=):x=y 把y的值赋给x!一直是true!
  • 严格相等运算符(===):x===y x等于y 优先采用
  • 相等运算符(==): x===y x等于y

if...else 结构:

if代码块后面,还可以跟一个else代码块,表示不满足条件时,所要执行的代码。

1.规则:

  • 先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。
  • 如果表达式的求值结果为true,就执行紧跟在表达式后面的语句1;如果结果为false,则执行else里的语句2

2.基本形式

if (表达式){
  语句1
}
   else{
  语句2
}

3.语句1里面可以有嵌套的if...else 结构

var m = 1;
var n = 2;
if (m !== 1)
if (n === 2) console.log('hello');
else console.log('world');

上面代码不会有任何输出,else代码块不会得到执行,因为它跟着的是最近的那个if语句,相当于下面这样。

if (m !== 1) {
  if (n === 2) {
    console.log('hello');
  } else {
    console.log('world');
  }
}

4.语句2里面可以有嵌套的if...else 结构

// 对一个变量多次进行判断
if (表达式一) {
  语句一;
} else {
  if (表达式二) {
    语句二;
  } else {
    if (表达式三) {
      语句三;
    } else {
      语句四;
    }
  }
}
// 去掉一些大括号,等同于
// 最推荐写法
if (表达式一) {
  语句一;
} else  if (表达式二) {
    语句二;
  } else  if (表达式三) {
      语句三;
    } else {
      语句四;
    }
function fn(){
  if (表达式) {
    return表达式
}
  if (表达式) {
    return表达式
}
return表达式
}

5.else代码块总是与离自己最近的前面的那个if语句配对。

6.缩进也可以很变态,如面试题常常下套

a=1
if(a===2)
  console.log('a')
  console.log( 'a等于2')
// a等于2 
  等同于 
a=1
if(a===2){
    console.log('a')
}
console.log( 'a等于2')

程序员戒律:使用没有歧义的写法

最推荐的写法

if(表达式){
    语句
}else if(表达式){
    语句
} else {
    语句

次推荐写法

function fn(){
    if (表达式){
        return 表示式
    }
    if (表达式){
        return 表达式
    return 表达式
}

return包含后面都不执行的意思,所以此时可以省略else,因为else的意思就是如果前面都没执行,就执行else之后的。

switch语句

1.基本结构

switch (fruit) {
  case "banana":
    // ...
    break;
  case "apple":
    // ...
    break;
  default:
    // ...
}

上面代码根据变量fruit的值,选择执行相应的case。如果所有case都不符合,则执行最后的default部分。

注:

  • case代码块之中没有break语句,导致不会跳出switch结构,而会一直执行下去
  • switch语句部分和case语句部分,都可以使用表达式。

问好冒号表达式(三元运算符 ?:)

1.基本形式

(表达式) ? 语句1 : 语句2

2.规则:如果“表达式”为true,则执行“语句1”,否则执行“语句2”

举例:

function max(a,b){
    if(a>b)return a;
    else return b;
}
//等同于
function max(a,b){
    return a>b ? a:b
}

便捷性: 能用问号冒号表达式的时候就不用if...else

&&短路逻辑

也是用来替代if else

A && B && C && D 取第一个假值或D,并不会取true或false

举例:


if(window.f1){
    console.log('f1存在')
}
//等同于
window.f1 && console.log('f1存在')

fn && fn()

fn存在就调用fn,不存在就不调用

|| 短路逻辑

A || B || C || D 取第一个真值或D,并不会取true或false

举例:


a||b
//等同于
if(!a){
  b
}else{a}
//如果a不存在,就执行b,否则还是a

a = a||100
//如果a存在就是a,如果a不存在就令a为100
//如果变量a存在,变量a就为第一个真值,再把变量a赋值给变量a,a还是a自己
//a不存在,那么第一个a不是真值,就执行最后一句a=100。给a一个保底值。
等同于
if(a){
    a=a
    } else{
      a=100 // 保底值
      }
//如果a不存在就令a为100,如果a存在就令a还是为a
等同于
if(!a){
    a=100 // 保底值
    } else{
      a=a
      }

循环语句

while(不推荐)

1.基本结构

while (表达式) {循环体语句}

2.规则:

  • 判断表达式的真假
  • 当表达式为真,执行语句,执行完再判断表达式的真假
  • 当表达式为假,执行后面的语句

注意:

容易死循环 (下面的代码将循环100次,直到i等于100为止)

var i = 0;  //初始化表达式
while (i < 100) {   //判断表达式
  console.log('i 当前为:' + i);  //循环体语句
  i = i + 1;    //递增表达式
}

浮点数不精确 (会进入死循环。因为浮点数a永远不会等于1)

while(a !== 1){
    console.log(a)
    a=a+0.1
}

for循环

1.基本结构

for (初始化表达式; 判断表达式; 递增表达式) {
  循环体语句
}

2.规则

  • 先执行初始化表达式
  • 再判断表达式的真假
  • 如果为真,就执行循环体语句,然后执行递增表达式
  • 如果为假,就直接退出循环,执行后边的语句

举例:

var x = 3;
for (var i = 0; i < x; i++) {
  console.log(i);
}
// 0
// 1
// 2
// 最后循环执行完i=3

上面面代码中,初始化表达式是var i = 0,即初始化一个变量i;判断表达式是i < x,即只要i小于x,就会执行循环;递增表达式是i++,即每次循环结束后,i增大1。

for(var i=0;i<3;i++){
    setTimeout(()=>{
    console.log(i)
    },0)
}
//3个3
/*
i=0满足i<3,所以执行循环体打出i,但要过一会。
以此类推
i=1满足i<3,所以执行循环体打出i,但要过一会。
i=2满足i<3,所以执行循环体打出i,但要过一会。
i=3不满足i<3,结束循环。
for循环不结束,就不算过一会!
现在循环结束了,过一会了,终于要打出i了,而且还要打出三次,因为此时i=3了。所以打出了3个3
*/

所有for循环,都可以改写成while循环。上面的例子改为while循环

var x = 3;
for (var i = 0; i < x; i++) {
  console.log(i);
}
// 0
// 1
// 2

上面代码中,初始化表达式是var i = 0,即初始化一个变量i;测试表达式是i < x,即只要i小于x,就会执行循环;递增表达式是i++,即每次循环结束后,i增大1

var x = 3;
var i = 0;
while (i < x) {
  console.log(i);
  i++;
}

break和continue

break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行。

break语句用于跳出代码块或循环。

var i = 0;
while(i < 100) {
  console.log('i 当前为:' + i);
  i++;
  if (i === 10) break;
}
//上面代码只会执行10次循环,一旦i等于10,就会跳出循环。

for循环也可以使用break语句跳出循环。

for (var i = 0; i < 5; i++) {
  console.log(i);
  if (i === 3)
    break;
}
// 0
// 1
// 2
// 3
//上面代码执行到i等于3,就会跳出循环。

continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。

var i = 0;
while (i < 100){
  i++;
  if (i % 2 === 0) continue;
  console.log('i 当前为:' + i);
}
//上面代码只有在i为奇数时,才会输出i的值。如果i为偶数,则直接进入下一轮循环。

如果存在多重循环,不带参数的break语句和continue语句都只针对最内层循环。

label

JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。

label:
  语句

举例:


foo:{
    console.log(1);
    break foo;
    console.log('本行不会输出');
}
//foo是一个标签,表示一个代码块
//1

{
    foo:1;
}
//这是一个代码块,代码块里有一个标签foo,标签foo的内容是1

数据类型

数值(number)

数值的存储方式

JS中,数字是用64位浮点数的形式存储的。(二进制)

网络异常,图片无法展示
|

其中符号占1位,指数部分有11位,范围从-1023到+1024,有效数字有 52 位,需要省略开头的 1 。 例如:0.5的存储方式是 0|-1|0 。

浮点数的范围

(1)最大值

  • 把指数部分11位和有效数字的52位全设为1(拉满),可得最大的二进制数字
  • 换成十进制为 Number.MAX_VALUE: 1.7976931348623157e+308

(2)最小值

  • 指数负方向拉满、有效数字最小1,得到最小的二进制数字
  • 换成十进制为Number.MIN_VALUE: 5e-324

精度

  • 最多只能到52+1个二进制位表示有效数字
  • 2^53对应的十进制是9后面15个零
  • 所以对于十进制来说15位数字都能精确表示
  • 16位有效数字如果小于90开头,也能精确表示
  • 91 10000000000001就存不下来

数值的表示法:

  • 整数 1
  • 小数 0.1
  • 科学计数法 1.23e4 (e4就是乘以10的4次方)
  • 八进制(用得少)0123,00123,0o123
  • 十六进制 0x3F 0X3F (用得少)
  • 二进制 0b11 或0B11 (用得少)

数值的进制

JavaScript 对整数提供四种进制的表示方法:十进制、十六进制、八进制、二进制

  • 十进制:没有前导0的数值
  • 八进制:有前缀0o或0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。如0123或00123或0o123
  • 十六进制:有前缀0x或0X的数值。如0x3F或0X3F
  • 二进制:有前缀0b或0B的数值。如0b11或0B11

特殊数值

  • 正0 和 负0都等于 0, 但是是三个数
  • 无穷大: Infinity 、+Infinity 、-Infinity
  • 无法表示的数字:NaN(Not a Number),但他是一个数字 。(比如0除以0,返回NaN) NaN不等于任何值,包括NaN。

方法

parseInt方法用于将字符串转为整数。parseFloat方法用于将一个字符串转为浮点数。isNaN方法可以用来判断一个值是否为NaNisFinite方法返回一个布尔值,表示某个值是否为正常的数值

布尔(bool)

只有两个值,true和false 下列运算符会返回布尔值:

  • 前置逻辑运算符: ! (Not)
  • 相等运算符:===!====!=
  • 比较运算符:>>=<<=

如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其他值都视为true

  • undefined
  • null
  • false
  • 0
  • NaN
  • ''(空字符串)

这五个 falsy 值代表假的。(还有false)

undefined和null

undefined 和 null 是两种空类型,区别如下:

  • 声明变量但是没有赋值,默认值是undefined,不是null。
  • 函数没有return,那么默认return undefined,而不是 null。
  • 习惯上,非对象的空值写为undefined,把对象的空值写为 null。

字符串(string)

1、写法

  • 单引号 'hi'
  • 双引号 "hi"
  • 反引号 ``

引号不属于字符串的一部分

2、转义

例如 'it's ok' ,JS引擎会认为 'it' 就结束了。

正确写法

  • 转义: 前面加斜杠 \ ,例如 'it's ok'
  • 外面用双引号:"it's ok"
  • 外面用反引号

转义——用另一种写法表示你想要的东西

  • ' —— ' 单引号
  • " —— " 双引号
  • \n —— 换行
  • \r —— 回车
  • \t —— tab 制表符
  • \ —— \斜杠
  • \uFFFF —— 对应的Unicode 字符
  • \xFF —— 前 256 个Unicode 字符
  • 多行字符串:外面用反引号

3、字符串长度

string.length —— 即可看见字符串string的长度 例如:'\n\r\t'.length //值为3

通过下标可以读取字符(类似数组) 例如:let s='hello';s[0] //值为"h"

4、base64转码

  • window.btoa(字符串)—— 正常字符串转为Base64编码的字符串
  • window.atob(字符串) —— Base64编码的字符串转为原来的字符串
  • 五、symbol符号

JS 中的 Symbol 是什么

三种声明方式

  • var a = 1 是过时的、不好用的方式
  • let a = 1 是新的,更合理的方式
  • const a = 1 是声明时必须赋值,且不能再改的方式
  • a = 1 最后这种方式是错误的,不准这样声明

let声明

  • 遵循块作用域,适用范围不能超过{}
  • 不能重复声明
  • 可以赋值,也可以不赋值
  • 必须先声明再使用
  • 全局声明的let变量,不会变成window属性
  • for循环配合let 有奇效

const声明

  • 跟let规则一样
  • 只有一条不同,声明时就要赋值,赋值后不能改

注意:声明变量的同时,也指定了类型,但是值和类型都可以随时变化

类型转换

1、number => string

  • String(n)
  • n+''
  • ''+n

2、string => number

  • Number(s)
  • parseInt(s)
  • parseFloat(s)
  • s-0
  • +s

3、x => bool

  • Boolean(x)
  • !!x一个感叹号可把任何东西取反布尔值,再来一个就是反布尔值的反布尔值,也就是原始布尔值

4、X => string

  • String(x)
  • x.toString()
  • 数字1不可用上面的,因为默认1.后面应是小数。bug!
  • (1).toString()
  • 1..toString()
  • 1 .toString()

对象

定义:

无序的数据集合

建制对的集合

写法:

  • 简便写法:let obj = { 'name': 'frank', 'age': 18 }
  • 正规写法:let obj = new Object({'name': 'frank'})
  • 匿名写法:console.log({ 'name': 'frank, 'age': 18 })
注意:
  • 键名是字符串!
  • 键名是字符串,不是标识符,可以包含任意字符
  • 引号可省略,省略之后就只能写标识符
  • 渲算引号省略了,键名也还是字符串(重要)

对象的属性

  • 属性名:每个key都是对象的属性名(property)
  • 属性值:每个 value 都是对象的属性值

奇怪的属性名:

所有属性名都会自动变成字符串

let obj = {
  1: 'a',
  3.2: 'b',
  1e2: true,
  1e-2: true,
  .234: true,
  0xFF: true
};
/** 以上每个属性的key值:
1其实是'1'
3.2其实是是'3.2'
1e2其实是'100'
1e-2其实是'0.01'
.234其实是'0.234'
0xFF其实是'255'

细节Object.keys(obj) 可以得到obj的所有key

变量做属性名:

如何使用变量做属性名?之前都是常量做属性名

let p1 = 'name'
let obj = { p1 : 'frank'} //这样写,属性名为 'p1'
let obj = { [p1] : 'frank' } //这样写,属性名为 'name'
  • 不加 [ ] 的属性名会自动变成字符串。
  • 加了 [ ] 则会当做变量求值。
  • 值如果不是字符串,则会自动变成字符串

3、对象的隐藏属性:

  • JS中每个对象都有一个隐藏属性__proto__
  • 这个隐藏属性储存着其共有属性组成的对象的地址
  • 这个由共有属性组成的对象window.Object.prototype叫做原型,也称为对象的根
  • 也就是说,每个object对象的隐藏属性__proto__储存着原型window.Object.prototype的地址
  • 每个对象都有原型
  • 原型也是个对象,所以也有原型,这不过原型的原型为null(空,但是是存在的)
var obj= {}
obj.toString() //居然不报错              
//因为obj的隐藏属性对应的对象上有toString()

除了字符串,symbol也能做属性名

let a = Symbol()
let obj = {[a]: 'Hello'}

对象属性的增删改查

删除属性

delete obj.xxxdelete obj['xxx']:即可删除obj的XXX属性,此时属性值当然也没有 注意比较区别:obj.xxx = undifined xxx属性名还在,只是属性值变为undifined

举例:

(1)

网络异常,图片无法展示
|

注:只能用'xxx' in obj 查看属性名是否还在对象中:true表示在,false表示不在

(2)

网络异常,图片无法展示
|

①语句'xxx' in obj && obj.xxx === undefined返回true,表示属性xxx还在obj中,而且属性xxx的值是undefined

②注意obj.xxx === undefined不能断定'xxx' 是否为obj的属性。

读属性

查看一个对象的所有属性:

  • 查看一个对象的所有自身属性: Object.keys(obj)
  • 查看一个对象的所有自身属性值: Object.values(obj)
  • 查看一个对象的所有自身的属性和值:直接对象名就行obj或者Object.entries(obj)
  • 查看自身+共有属性: console.dir(obj)
  • 查看共有属性: 自己依次用Object.keys打印出obj.__ proto_
  • 判断一个属性是自身的还是共有的: obj.hasOwnProperty('属性名')( 返回true说明该属性是自身属性,返回false说明该属性是共有属性)
  • 'key' in obj查看属性名是否还在对象中:true表示在,false表示不在

查看一个对象的一个属性

  • 中括号语法: obj['key']obj['k'+'ey']
  • 点语法: obj.key
  • 坑新人语法:obj[key] // 变量 key 值一般不为 'key'

举例

let list = ['name','age','gender']
let person = {
    name: 'yy', age : 18, gender : 'woman'
}
for (let i = 0; i < list.length; i++) {
    let name = list [i]
    console.log(person.name)  //重点
}
// 结果为person的第一个属性值yy*3
let list = ['name','age','gender']
let person = {
    name: 'yy', age : 18, gender : 'woman'
}
for (let i = 0; i < list.length; i++) {
    let name = list [i]
    console.log(person[name]) //重点
}
// 结果为person的所有属性值yy、18、woman

写属性

1、修改或增加属性

(1)直接赋值

let obj = {name: 'frank'} // name 是字符串
obj.name = 'frank' // name 是字符串
obj['name'] = 'frank'
***obj[name] = 'frank' // 错,因 name 值不确定
obj['na'+'me'] = 'frank'
let key = 'name'; obj[key] = 'frank'
let key = 'name'; ***obj.key = 'frank'~~ // 错,因为 obj.key 等价于 obj['key']

(2)批量赋值

Object.assign(obj, {age: 18, gender: 'man'})

2、修改或增加公有属性

无法通过自身修改或增加共有属性

  • let obj = {}, obj2 = {} 共有 toString
  • obj.toString = 'xxx' 只会在改 obj 自身属性
  • obj2.toString 还是在原型上

我偏要修改或增加原型上的属性

  • obj.__proto__.toString = 'xxx' // 不推荐用 __proto__
  • Object.prototype.toString = 'xxx'
  • 一般来说,不要修改原型,会引起很多问题

3、修改隐藏属性

不推荐使用__proto__

let obj = {name:'frank'}
let obj2 = {name: 'jack'}
let common = {kind: 'human'}
obj.__proto__ = common
obj2.__proto__ = common

推荐使用 Object.create

let obj = Object.create(common)
obj.name = 'frank'
let obj2 = Object.create(common)
obj2.name = 'jack'

规范大概的意思是,要改就一开始就改,别后来再改

数组

待补充,贴一篇大佬的文JS数组奇巧淫技 - 掘金 (juejin.cn)

相关文章
|
6月前
|
JavaScript 前端开发 API
|
13天前
|
自然语言处理 JavaScript 前端开发
[JS]知识点
本文介绍了JavaScript中的多个重要知识点,包括ES6、严格模式、类与对象、解构、跨域问题及入口函数等。文章通过详细示例和推荐的外部资源,帮助读者更好地理解和应用这些概念。内容持续更新中,适合初学者和进阶开发者参考。
11 2
[JS]知识点
|
6月前
|
JavaScript 前端开发 CDN
总结 vue3 的一些知识点:Vue.js 安装
总结 vue3 的一些知识点:Vue.js 安装
|
6月前
|
JavaScript
总结 vue3 的一些知识点:​Vue.js 条件语句​
总结 vue3 的一些知识点:​Vue.js 条件语句​
|
13天前
|
JavaScript 前端开发 中间件
JS服务端技术—Node.js知识点
本文介绍了Node.js中的几个重要模块,包括NPM、Buffer、fs模块、path模块、express模块、http模块以及mysql模块。每部分不仅提供了基础概念,还推荐了相关博文供深入学习。特别强调了express模块的使用,包括响应相关函数、中间件、Router和请求体数据解析等内容。文章还讨论了静态资源无法访问的问题及其解决方案,并总结了一些通用设置。适合Node.js初学者参考学习。
30 1
|
21天前
|
存储 JavaScript 前端开发
JS的ES6知识点
【10月更文挑战第19天】这只是 ES6 的一些主要知识点,ES6 还带来了许多其他的特性和改进,这些特性使得 JavaScript 更加现代化和强大,为开发者提供了更多的便利和灵活性。
15 3
|
1月前
|
存储 JSON JavaScript
JS知识点
JS知识点
20 3
|
1月前
|
JavaScript 前端开发 Java
【javaScript数组,函数】的基础知识点
【javaScript数组,函数】的基础知识点
23 5
|
2月前
|
JavaScript 前端开发 Java
JavaScript 类知识点概览
概览JavaScript中类的知识点,包括类的定义和实现、添加方法和get/set方法、类的继承和静态方法的使用。通过学生类和人员类的例子,演示了类的构造器、方法定义、继承关系和静态方法的调用。
JavaScript 类知识点概览
|
1月前
|
前端开发 JavaScript
JavaScript 知识点总结
JavaScript 知识点总结
27 0