JavaScript基础整理(一)

数据类型
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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,477评论 1 11
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,550评论 0 5
  • JavaScript语言精粹 前言 约定:=> 表示参考相关文章或书籍; JS是JavaScript的缩写。 本书...
    微笑的AK47阅读 578评论 0 3
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,146评论 0 3
  • JavaScript的组成 JavaScript 由以下三部分组成:ECMAScript(核心):JavaScri...
    纹小艾阅读 3,171评论 0 3