JavaScript高级之基础总结

一、JavaScript基础总结

1、数据类型相关知识点

Ⅰ-基本(值)类型

  1. String: 任意字符串
  2. Number: 任意的数字
  3. boolean: true/false
  4. undefined: undefined
  5. null: null -->使用typeof时返回object
  6. symbol (ECMAScript 2016新增)。 -->Symbol 是 基本数据类型 的一种,Symbol 对象是 Symbol原始值的封装 (en-US)
  7. bigint, -->BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数。

加上下方的 [ 对象 ] 类型,目前 javaScript 有八种数据类型

Ⅱ-对象(引用)类型

  1. Object: 任意对象
  2. Function: 一种特别的对象(可以执行) --内部包含可运行的代码
  3. Array: 一种特别的对象(key为数值下标属性, 内部数据是有序的)

Ⅲ-判断方法

①* typeof*

typeof 操作符返回一个字符串,表示未经计算的操作数的类型。

  • 可以判断: undefined/ 数值 / 字符串 / 布尔值 / function

  • 不能判断: null与object object与array

  • 注意: 运行console.log(typeof undefined)时,得到的的也是一个字符串,同时为小写!!–> 'undefined'

  • 代码示例

 // typeof返回数据类型的字符串表达
 var a

 //注意:typeof返回的是字符串
 console.log(a, typeof a, typeof a==='undefined',a===undefined )  // undefined 'undefined' true true
 console.log(undefined === 'undefined') //false
 a = 4
 console.log(typeof a==='number') //true
 a = 'hongjilin'
 console.log(typeof a==='string') //true
 console.log(typeof a==='String') //false  -->注意,返回的类型为小写
 a = true
 console.log(typeof a==='boolean') //true
 a = null
 console.log(typeof a, a===null) // 'object'  true
let b={}
 console.log(typeof b,typeof null, '-------') // 'object' 'object'  -->所以Typeof不能判断null与object
②*instanceof*(判断实例方法)
  • 专门判断对象的具体类型

  • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

  • 代码示例:

 var b1 = {
   b2: [1, 'abc', console.log],
//可以简化成 b3:()=>()=> 'hongjilin'  -->高阶函数相关知识
   b3: function () {
     return  () =>{  return   'hongjilin'}
   }
 }
/**使用instanceof进行对象判断*/
 console.log(b1 instanceof Object, b1 instanceof Array) // true  false
 console.log(b1.b2 instanceof Array, b1.b2 instanceof Object) // true true
 console.log(b1.b3 instanceof Function, b1.b3 instanceof Object) // true true

 /**使用typeof进行对象中某属性的判断*/
console.log(typeof b1.b2, typeof null) // 'object' 'object'  
 console.log(typeof b1.b3==='function') // true
 console.log(typeof b1.b2[2]==='function') //true

 /**调用对象与数组中某函数示例*/
 b1.b2[2]('调用console.log打印hongjilin')    //调用console.log打印hongjilin
 console.log(b1.b3()()) // hongjilin
③*===*

具体可以看 MDN的JavaScript中的相等性判断

可以判断: undefined, null

简而言之,在比较两件事情时,双等号将执行类型转换; 三等号将进行相同的比较,而不进行类型转换 (如果类型不同, 只是总会返回 false )

Ⅳ-相关问题引出

undefined与null的区别?
  • undefined代表定义未赋值

  • nulll定义并赋值了, 只是值为null

  • 代码示例

var a
console.log(a)  // undefined
a = null
console.log(a) // null
什么时候给变量赋值为null呢?
  • 初始赋值, 表明将要赋值为对象,可以用做约定俗成的占位符

  • 结束前, 让对象成为垃圾对象(被垃圾回收器回收)

  • 代码示例

//起始,可以用做约定俗成的占位符
var b = null  // 初始赋值为null, 表明将要赋值为对象
//确定对象就赋值
b = ['atguigu', 12]
//最后在不使用的时候,将其引用置空,就可以释放b这个对象占用的内存      ---当没有引用指向它的对象称为垃圾对象
b = null // 让b指向的对象成为垃圾对象(被垃圾回收器回收)
严格区别变量类型与数据类型?
  • 数据的类型
  • 基本类型
  • 对象类型
  • 变量的类型(变量内存值的类型)
  • 基本类型: 保存就是基本类型的数据
  • 引用类型: 保存的是地址值(对象类型)

Ⅴ-补充知识点:

①符串对比*><以及charCodeAt()*方法
  1. Javascript字符串在进行大于(小于)比较时,会根据第一个不同的字符的ascii值码进行比较,当数字(number)与字符串(string)进行比较大小时,会强制的将数字(number)转换成字符串(string)然后再进行比较
(function(){
  console.log('13'>'3'); // 输出:false
  console.log(5>'6');  // 输出: false
  console.log('d'>'ABDC') // 输出: true
  console.log(19>'ssf') // 输出 false
  console.log('A'>'abcdef') // 输出 false
})()
  1. 手动转换为ascii后相减,用正负数表示大小
sorter={(a:string,b:string)=> a.charCodeAt()-b.charCodeAt()}

2、数据,变量, 内存的理解

Ⅰ-什么是数据?

  1. 存储在内存中代表特定信息的’东西’, 本质上是0101…
  2. 数据的特点: 可传递, 可运算 -->let a=0;b=a 🔜体现可传递
  3. 一切皆数据
  4. 内存中所有操作的目标:数据
  • 算术运算

  • 逻辑运算

  • 赋值

  • 运行函数

Ⅱ-什么是内存?

  1. 内存条通电后产生的可储存数据的空间(临时的)

  2. 内存产生和死亡:内存条(电路版)>通电>产生内存空间==>存储数据==>处理数据==>断电==>内存空间和数据都消失

  3. 一块小内存的2个数据

  • 内部存储的数据

  • 地址值

  1. 内存分类
  • 栈: 全局变量/局部变量

  • 堆: 对象

Ⅲ-什么是变量?

  • 可变化的量, 由变量名和变量值组成
  • 每个变量都对应的一块小内存, 变量名用来查找对应的内存, 变量值就是内存中保存的数据

ps:变量obj.xx–>.相当于拿着地址找到后面对应的内存,所以只有当我变量中存的是地址,才可以用.

Ⅳ-内存,数据, 变量三者之间的关系

  • 内存是用来存储数据的空间
  • 变量是内存的标识

Ⅴ-相关问题引出

关于赋值和内存的问题

let a = xxx, a内存中到底保存的是什么?

  • xxx是基本数据, 保存的就是这个数据
  • xxx是对象, 保存的是对象的地址值
  • xxx是一个变量, 保存的xxx的内存内容(可能是基本数据, 也可能是地址值)
关于引用变量赋值问题
  • 2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据

  • 2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象

  • 代码示例:

let a = {age: 12}
//此时是将a指向的地址值赋值给B,所以B此时也指向{age:12}这个内存
let b = a
//此时重新创建了一个内存并让a指向它,所以此处a指向的是{name:'hong'},而b指向仍是刚开始的指向{age:12}
a = {name: 'hong'}
//此时a与b指向的内存已经不一样了,所以修改互不影响
b.age = 14
console.log(b.age, a.name, a.age) // 14 hong undefined
//2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象   -->所以 a 仍是  {name: 'hong'}
const fn2=(obj) => obj = {age: 15}
fn2(a)
console.log(a.age) //undefined 
在js调用函数时传递变量参数时, 是值传递还是引用传递
  • 理解1: 都是值(基本/地址值)传递

  • 所以实际上传进function中的参数也是拿着其存着的地址值找内存

//传进来的obj存储的是a中存的地址值,所以obj==a(因为他们地址值一致,指向一致)
//2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据  -->所以被进行了修改
 let a = {name: 'hong'}
 const fn2=(obj) => obj.age= 15
 fn2(a)
 console.log(a.age) //15
  • 理解2: 可能是值传递, 也可能是引用传递(地址值)
JS引擎如何管理内存?
  1. 内存生命周期
  • 分配小内存空间, 得到它的使用权

  • 存储数据, 可以反复进行操作

  • 释放小内存空间

  1. 释放内存
  • 局部变量: 函数执行完自动释放

  • 对象: 成为垃圾对象==>垃圾回收器回收

var a = 3
var obj = {name:"hong"}
obj = undefined ||null  //此时,obj没有被释放,但是之前声明的`{name:"hong"}`由于没有人指向它,会在后面你某个时刻被垃圾回收器回收

function fn () { var b = {}}
fn() // b是自动释放, b所指向的对象是在后面的某个时刻由垃圾回收器回收

3、对象

Ⅰ-对象的概念

什么是对象?
  • 多个数据的封装体
  • 用来保存多个数据的容器
  • 一个对象代表现实中的一个事物
为什么要用对象?
  • 统一管理多个数据
对象的组成
  • 属性: 属性名(字符串)和属性值(任意)组成
  • 方法: 一种特别的属性(属性值是函数)

Ⅱ-如何访问对象内部数据?

  • .属性名: 编码简单, 有时不能用
  • ['属性名']: 编码麻烦, 能通用

Ⅲ-什么时候必须使用['属性名']的方式?

  1. 属性名包含特殊字符: - 空格
  2. 属性名不确定
var p = {}
//1. 给p对象添加一个属性: content type: text/json
// p.content-type = 'text/json' //不能用
p['content-type'] = 'text/json'
console.log(p['content-type'])

//2. 属性名不确定
var propName = 'myAge'
var value = 18
// p.propName = value //不能用
p[propName] = value
console.log(p[propName])

4、函数

Ⅰ-函数的概念

什么是函数
  • 实现特定功能的n条语句的封装体
  • 只有函数是可以执行的, 其它类型的数据不能执行
为什么要用函数?
  • 提高代码复用
  • 便于阅读交流
如何定义函数?
  • 函数声明

  • 表达式

function fn1 () { //函数声明
  console.log('fn1()')
}
var fn2 = function () { //表达式
  console.log('fn2()')
}

Ⅱ-如何调用(执行)函数

  1. test(): 直接调用

  2. obj.test(): 通过对象调用

  3. new test(): new调用

  4. test.call/apply(obj): 临时让test成为obj的方法进行调用

> * [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBWIrieV-1650369482428)(.\JavaScript高级.assets\image-20210705185535337.png)]

  1. 代码示例
  var obj = {}
  //此处不能使用箭头函数,因为箭头函数会改变this指向
  function test2 () {
    this.xxx = 'hongjilin'
  }
  // obj.test2()  不能直接, 根本就没有
  test2.call(obj)  // 可以让一个函数成为指定任意对象的方法进行调用
  console.log(obj.xxx)

Ⅲ-回调函数

什么函数才是回调函数?
  • 你定义的
  • 你没有调
  • 但最终它执行了(在某个时刻或某个条件下)
常见的回调函数?
  • dom事件回调函数 ==>发生事件的dom元素
  • 定时器回调函数 ===>window
  • ajax请求回调函数(后面讲)
  • 生命周期回调函数(后面讲)
document.getElementById('btn').onclick = function () { // dom事件回调函数
  alert(this.innerHTML)
}
setTimeout(function () { // 定时器回调函数

  alert('到点了'+this)
}, 2000)

Ⅳ-IIFE (自调用函数)

  1. 全称: Immediately-Invoked Function Expression 自调用函数

  2. 作用:

  • 隐藏实现

  • 不会污染外部(一般指全局)命名空间

  • 用它来编码js模块

  1. 代码示例
  (function () { //匿名函数自调用
      var a = 3
      console.log(a + 3)
  })()
  console.log(a) // a is not defined

  //此处前方为何要一个`;`-->因为自调用函数外部有一个()包裹,可能与前方以()结尾的代码被一起认为是函数调用
  //不加分号可能会被认为这样 console.log(a)(IIFE)
  ;(function () {//不会污染外部(全局)命名空间-->举例
      var a = 1;

      function test() {
          console.log(++a)
      } //声明一个局部函数test
      window.$ = function () {
          return {
              test: test
          }
      }// 向外暴露一个全局函数
  })()
  test()  //test is not defined
  $().test() // 1. $是一个函数 2. $执行后返回的是一个对象

Ⅴ-函数中的this

this是什么?
  • 任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window
  • 所有函数内部都有一个变量this
  • 它的值是调用函数的当前对象
如何确定this的值?
  • test(): window
  • p.test(): p
  • new test(): 新创建的对象
  • p.call(obj): obj
代码举例详解
function Person(color) {
  console.log(this)
  this.color = color;
  this.getColor = function () {
      console.log(this)
      return this.color;
  };
  this.setColor = function (color) {
      console.log(this)
      this.color = color;
  };
}

Person("red"); //this是谁? window

const p = new Person("yello"); //this是谁? p

p.getColor(); //this是谁? p

const obj = {};
//调用call会改变this指向-->让我的p函数成为`obj`的临时方法进行调用
p.setColor.call(obj, "black"); //this是谁? obj

const test = p.setColor;
test(); //this是谁? window  -->因为直接调用了

function fun1() {
  function fun2() {
      console.log(this);
  }

  fun2(); //this是谁? window
}

fun1();//调用fun1

5、关于语句分号

  1. js一条语句的后面可以不加分号
  2. 是否加分号是编码风格问题, 没有应该不应该,只有你自己喜欢不喜欢
  3. 在下面2种情况下不加分号会有问题
  • 小括号开头的前一条语句
  • 中方括号开头的前一条语句
  1. 解决办法: 在行首加分号
  2. 强有力的例子: vue.js库
  3. 知乎热议: https://www.zhihu.com/question/20298345
	var a = 3
    ;(function () {

    })()
    /*
     错误理解
     var a = 3(function () {

     })();
    */

    var b = 4
    ;[1, 3].forEach(function () {

    })
    /*
    错误理解
     var b = 4[3].forEach(function () {

     })
     */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值