美文网首页JS
JavaScript基础整理(一)

JavaScript基础整理(一)

作者: 肉桂猿 | 来源:发表于2020-03-20 14:41 被阅读0次

数据类型
null 和 undefined
== 和 ===
JS 比较对象和基本类型
!! 运算符
JavaScript 中的虚值
一行中计算多个表达式的值
作用域
作用域链
什么是提升
this指针
IIFE
new操作符
事件流
addEventListener
event.preventDefault() 和 event.stopPropagation()
event.target 和 event.currentTarget
闭包 Closure

  • JavaScript是单线程的语言

  • 数据类型
    基本数据类型: NumberStringBooleanNullUndefined
    引用数据类型: Object 是 JavaScript 中所有对象的父对象
    新类型:SymbolbigInt

基本数据类型存储在栈中,占据空间小、大小固定,属于被频繁使用数据;
引用数据类型存储在堆中,指针放在栈中。占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。


  • null 和 undefined
    相似处 -
  1. 属于JS基本类型。
let primitiveTypes = ['string','number','null','undefined','boolean','symbol', 'bigint'];
  1. 是虚值,可以使用Boolean(value)!!value将其转换为布尔值时,值为false。
console.log(!!null); // false
console.log(!!undefined); // false

console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false

区别 -
null是“不代表任何值的值”。null是已明确定义给变量的值。表示一个对象被定义了,但存放了空指针,转换为数值时为0
undefined是未指定特定值的变量的默认值,或者没有显式返回值的函数,如:console.log(1),还包括对象中不存在的属性,这些 JS 引擎都会为其分配 undefined 值。,转换为数值时为NAN

typeof(null) -- object;
typeof(undefined) -- undefined
console.log(null == undefined); // true
 console.log(null === undefined); // false

  • == 和 ===
    ==用于一般比较,会执行隐式强制转换数据类型。
    ===用于严格比较,只要类型不匹配就返回false。
假设我们要比较x == y的值。

如果x和y的类型相同,则 JS 会换成===操作符进行比较。
如果x为null, y为undefined,则返回true。
如果x为undefined且y为null,则返回true。
如果x的类型是number, y的类型是string,那么返回x == toNumber(y)。
如果x的类型是string, y的类型是number,那么返回toNumber(x) == y。
如果x为类型是boolean,则返回toNumber(x)== y。
如果y为类型是boolean,则返回x == toNumber(y)。
如果x是string、symbol或number,而y是object类型,则返回x == toPrimitive(y)。
如果x是object,y是string,symbol则返回toPrimitive(x) == y。
剩下的 返回 false

  • JS 比较对象和基本类型
    在基本类型中,JS 通过值对它们进行比较,而在对象中,JS 通过引用或存储变量的内存中的地址对它们进行比较。
let a = { a: 1 };
let b = { a: 1 };
let c = a;

console.log(a === b); // 打印 false,即使它们有相同的属性
console.log(a === c); // true

  • !! 运算符
    !!运算符可以将右侧的值强制转换为布尔值,这也是将值转换为布尔值的一种简单方法。
console.log(!!null); // false
console.log(!!undefined); // false
console.log(!!''); // false
console.log(!!0); // false
console.log(!!NaN); // false
console.log(!!' '); // true
console.log(!!{}); // true
console.log(!![]); // true
console.log(!!1); // true
console.log(!![].length); // false

  • JavaScript 中的虚值
const falsyValues = ['', 0, null, undefined, NaN, false];

简单的来说虚值就是是在转换为布尔值时(使用 Boolean 函数或者 !! 运算符)变为 false 的值。


  • 一行中计算多个表达式的值
    使用逗号运算符在一行中计算多个表达式。它从左到右求值,并返回右边最后一个项目或最后一个操作数的值。
let x = 5;
x = (x++ , x = addFive(x), x *= 2, x -= 5, x += 10);
function addFive(num) {
  return num + 5;
}

  • 作用域
    JS 有三种类型的作用域:全局作用域、函数作用域和块作用域(ES6)。
  1. 全局作用域——在全局命名空间中声明的变量或函数位于全局作用域中,因此在代码中的任何地方都可以访问它们。
  2. 函数作用域——在函数中声明的变量、函数和参数可以在函数内部访问,但不能在函数外部访问。
  3. 块作用域-在块{}中声明的变量(letconst)只能在其中访问。

  • 作用域链
    作用域也是一组用于查找变量的规则。如果变量在当前作用域中不存在,它将向外部作用域中查找并搜索,如果该变量不存在,它将再次查找直到到达全局作用域,如果找到,则可以使用它,否则引发错误,这种查找过程也称为作用域链。

  • 什么是提升
    执行上下文是当前正在执行的“代码环境”。执行上下文有两个阶段:编译和执行。

编译-在此阶段,JS 引荐获取所有函数声明并将其提升到其作用域的顶部,以便我们稍后可以引用它们并获取所有变量声明(使用var关键字进行声明),还会为它们提供默认值:undefined。

执行——在这个阶段中,它将值赋给之前提升的变量,并执行或调用函数(对象中的方法)。

注意:只有使用var声明的变量,或者函数声明才会被提升,相反,函数表达式或箭头函数,let和const声明的变量,这些都不会被提升。

console.log(y);
y = 1;
console.log(y);
console.log(greet("Mark"));

function greet(name){
  return 'Hello ' + name + '!';
}

var y;

上面分别打印:undefined,1, Hello Mark!
上面代码在编译阶段其实是这样的:

function greet(name) {
  return 'Hello ' + name + '!';
}

var y; // 默认值 undefined

// 等待“编译”阶段完成,然后开始“执行”阶段

/*
console.log(y);
y = 1;
console.log(y);
console.log(greet("Mark"));
*/

编译阶段完成后,它将启动执行阶段调用方法,并将值分配给变量。

function greet(name) {
  return 'Hello ' + name + '!';
}

var y;

//start "execution" phase

console.log(y);
y = 1;
console.log(y);
console.log(greet("Mark"));

  • this指针
  1. this总是指向函数的直接调用者(而非间接调用者)
  2. 如果有new关键字,this指向new出来的那个对象
  3. 在事件中,this指向目标元素,特殊的是IE的attachEvent中的this总是指向全局对象window
    this指的是当前正在执行或调用该函数的对象的值。this值的变化取决于我们使用它的上下文和我们在哪里使用它。
const carDetails = {
  name: "Ford Mustang",
  yearBought: 2005,
  getName(){
    return this.name;
  },
  isRegistered: true
};

console.log(carDetails.getName()); // Ford Mustang

这通常是我们期望结果的,因为在getName方法中我们返回this.name,在此上下文中,this指向的是carDetails对象,该对象当前是执行函数的“所有者”对象。
接下我们做些奇怪的事情:

var name = "Ford Ranger";
var getCarName = carDetails.getName;

console.log(getCarName()); // Ford Ranger

在全局作用域中使用var关键字声明变量会在window对象中附加与变量名称相同的属性。
解决这个问题的一种方法是在函数中使用applycall方法。applycall方法期望第一个参数是一个对象,该对象是函数内部this的值。

console.log(getCarName.apply(carDetails)); // Ford Mustang
console.log(getCarName.call(carDetails));  // Ford Mustang

  • IIFE
    IIFE或立即调用的函数表达式是在创建或声明后将被调用或执行的函数。
(function(){
  ...
} ());

(function () {
  ...
})();

(function named(params) {
  ...
})();

(() => {
});

(function (global) {
  ...
})(window);

const utility = (function () {
  return {
    ...
  }
})

经典面试题目:

var li = document.querySelectorAll('.list-group > li');
for (var i = 0, len = li.length; i < len; i++) {
   (function (currentIndex) {
      li[currentIndex].addEventListener('click', function (e) {
         console.log(currentIndex);
      })
   })(i);
}

IIFE会为每次迭代创建一个新的作用域,我们捕获i的值并将其传递给currentIndex参数,因此调用IIFE时,每次迭代的currentIndex值都是不同的。


  • new操作符
  1. 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
  2. 属性和方法被加入到 this 引用的对象中。
  3. 新创建的对象由 this 所引用,并且最后隐式的返回 this

  • 事件流
    事件流分为三个阶段,捕获节点 ->目标节点 -> 冒泡
    捕获节点 是从根节点(window)开始执行,一直往子节点查找执行,直到查找执行到目标节点;
    冒泡 是从目标节点开始执行,一直往父节点冒泡查找执行,直到查到根节点(window)。

  • addEventListener
    具有第三个可选参数useCapture,其默认值为false,事件将在冒泡阶段中发生,如果为true,则事件将在捕获阶段中发生。
el.addEventListener(event, callback, isCapture);

  • event.preventDefault() 和 event.stopPropagation()
    event.preventDefault() 方法可防止元素的默认行为。如果在表单元素中使用,它将阻止其提交。如果在锚元素中使用,它将阻止其导航。如果在上下文菜单中使用,它将阻止其显示或显示。event.stopPropagation()方法用于阻止捕获和冒泡阶段中当前事件的进一步传播。
    我们可以在事件对象中使用event.defaultPrevented属性。它返回一个布尔值用来表明是否在特定元素中调用了event.preventDefault()

  • event.target 和 event.currentTarget
    event.target是发生事件的元素或触发事件的元素
    event.currentTarget是我们在其上显式附加事件处理程序的元素
<div onclick="clickFunc(event)" style="text-align: center;margin:15px;
border:1px solid red;border-radius:3px;">
    <div style="margin: 25px; border:1px solid royalblue;border-radius:3px;">
        <div style="margin:25px;border:1px solid skyblue;border-radius:3px;">
          <button style="margin:10px">
             Button
          </button>
        </div>
    </div>
 </div>
function clickFunc(event) {
  console.log(event.target);// 打印 button 标签
console.log(event.currentTarget);// 打印最外面的div标签
}

  • 闭包 Closure
    JS Closure
    闭包指的是一个函数可以访问另一个函数作用域中变量。
    常见的构造方法,是在一个函数内部定义另外一个函数。内部函数可以引用外层的变量;外层变量不会被垃圾回收机制回收。
    注意,闭包的原理是作用域链,所以闭包访问的上级作用域中的变量是个对象,其值为其运算结束后的最后一个值。
    优点:避免全局变量污染。缺点:容易造成内存泄漏。
image.png
image.png

相关文章

  • JavaScript基础整理(一)

    数据类型null 和 undefined== 和 ===JS 比较对象和基本类型!! 运算符JavaScript ...

  • Javascript 基础干货大全

    汇总整理大前端 Javascript 基础干货大全 END

  • 前端基础整理 | Javascript基础 (一)

    个人向,对JS知识进行了查漏补缺,主要来源于《JS高级程序设计》和网上博客,本文内容主要包括以下: 在HTML中引...

  • JavaScript基础知识小记

    前言 最近发现自己许多JavaScript基础知识掌握不牢固。趁空闲时间,整理一下JavaScript的基础知识。...

  • JavaScript基础整理(三)

    eval它的功能是把对应的字符串解析成JS代码并运行;应该避免使用eval,不安全,非常耗性能(2次,一次解析成j...

  • JavaScript基础整理(二)

    Set + 扩展运算符... : 过滤原数组重复值。数组中数值类型为 undefined, null, boole...

  • 2021-11-29

    前端工程师要学的东西太多了,最近整理了一下。 一、JavaScript基础 变量和类型 JavaScript规定了...

  • 前端工程师的自检

    前端工程师要学的东西太多了,最近整理了一下。 一、JavaScript基础 变量和类型 JavaScript规定了...

  • Javascript基础随笔整理(一):array

    引用MDN注释: JavaScript的Array对象是用于构造数组的全局对象,数组是类似于列表的高阶对象。 一、...

  • 第二章 在HTML中使用JavaScript

    前言 最近开始重拾JavaScript基础,会将《JavaScript高级程序设计》这本书的知识点做一个整理,以方...

网友评论

    本文标题:JavaScript基础整理(一)

    本文链接:https://www.haomeiwen.com/subject/irqthhtx.html