【JS筆記】二凝果、javascript中的變量和數(shù)據(jù)類型 2022-04-11

9-JS的組成和變量

推薦書籍

《Javascript高級(jí)程序設(shè)計(jì)》
《ES6標(biāo)準(zhǔn)入門》 es6.ruanyifeng.com
《Javascript權(quán)威指南》
《你不知道的Javascript》上中下

JS做客戶端語(yǔ)言

按照相關(guān)的JS語(yǔ)法,去操作頁(yè)面中的元素生真,有時(shí)還要操作瀏覽器里面的一些功能

  • ECMA Script3/5/6: JS的語(yǔ)法規(guī)范(變量莫鸭、數(shù)據(jù)類型、操作語(yǔ)句等等)
    如烘嘱,使用var還是let
  • DOM(document object model):文檔對(duì)象模型昆禽,提供一些JS的屬性和方法,用來(lái)操作頁(yè)面中的DOM元素
  • BOM(browser object model):瀏覽器對(duì)象模型蝇庭,提供一些JS的屬性和方法醉鳖,用來(lái)操作瀏覽器
    把整個(gè)瀏覽器刷新,實(shí)現(xiàn)瀏覽器頁(yè)面跳轉(zhuǎn)哮内,關(guān)掉瀏覽器當(dāng)前窗口盗棵,關(guān)掉窗口前做相關(guān)提示,檢查當(dāng)前瀏覽器版本等

JS中的變量(variable)

變量:可變的量北发,在編程語(yǔ)言中纹因,變量其實(shí)就是一個(gè)名字,用來(lái)存儲(chǔ)和代表不同的東西

10-創(chuàng)建變量的幾種方式

創(chuàng)建變量的幾種方式

  // ES3琳拨、5
  /* var沒(méi)有變量的作用域瞭恰,是JS設(shè)計(jì)早期的一個(gè)缺陷,在ES6中改掉了狱庇,一般用let定義變量惊畏,用const定義常量 */
  var a = 12;
  a=13;
  console.log(a); // =>輸出的是a代表的值13

  // ES6
  let b = 100;
  b = 200;

  const c = 1000;
  c = 2000; // =>報(bào)錯(cuò):const創(chuàng)建的變量,存儲(chǔ)的值不能被修改密任,特殊變量颜启,(可以理解為叫做常量)
  本身具體的東西是真正的常量,而起的名字是變量浪讳,名字可以指向其他東西缰盏;const本身起的是名字

  // 創(chuàng)建函數(shù)也相當(dāng)于在創(chuàng)建變量
  function fn() {} // =>相當(dāng)于創(chuàng)建一個(gè)變量名叫fn,fn存的是整個(gè)函數(shù)
  // 創(chuàng)建類也相當(dāng)于創(chuàng)建變量
  class A{} // =>創(chuàng)建一個(gè)變量名叫A驻债,存的是整個(gè)類
  // ES6的模塊導(dǎo)入也可以創(chuàng)建變量
  import B from './B.js'; // =>導(dǎo)入一個(gè)模塊,創(chuàng)建一個(gè)變量名B形葬,存儲(chǔ)這個(gè)模塊的一些信息
  // Symbol創(chuàng)建唯一值
  let n = Symbol(100); 
  let m = Symbol(100); 
  n == m // =>false

11-JS命名規(guī)范

JS命名規(guī)范

  • 嚴(yán)格區(qū)分大小寫
let Test = 100;
console.log(test); // =>無(wú)法輸出
  • 使用數(shù)字合呐、字母、下劃線笙以、$淌实,數(shù)字不能作為開(kāi)頭
let $box; // =>一般用JQuery獲取的以$開(kāi)頭
let _box; // =>一般公共變量都是_開(kāi)頭,公共變量/全局變量(約定俗成猖腕,非官方規(guī)范)
let 1box; // =>不可以拆祈,但是可以寫box1
  • 使用駝峰命名法:首字母小寫,其余每一個(gè)有意義單詞的首字母都要大寫(命名盡可能語(yǔ)義化明細(xì)倘感,使用英文單詞)
let studentInformation;
let studentInfo;
// 常用的縮寫:add/insert/create/new(新增)放坏、update(修改)、delete/del/remove/rm(刪除)老玛、sel/select/query/get(查詢)淤年、info(信息)...

// 不正確的寫法
let xueshengInfo;
let xueshengxinxi;
let xsxx;
  • 不能使用關(guān)鍵字和保留字
當(dāng)下有特殊含義的是關(guān)鍵字钧敞,未來(lái)可能會(huì)成為關(guān)鍵字的叫做保留字(?)
var let Cindy function …
var var = 10; //=>肯定不行的
// =>代碼強(qiáng)迫癥(代碼潔癖):良好的編程習(xí)慣麸粮、極客精神

12-JS中的數(shù)據(jù)類型分類

JS中常用的數(shù)據(jù)類型

  • 基本數(shù)據(jù)類型
    • 數(shù)字number
      常規(guī)數(shù)字和NaN
    • 字符串string
      所有用單引號(hào)溉苛、雙引號(hào)、反引號(hào)(撇)包起來(lái)的都是字符串
      反引號(hào)包起來(lái)的是ES6新加的模板字符串
      如 '{name:10}' 是字符串
    • 布爾boolean
      true/false
    • 空對(duì)象指針null
    • 未定義undefined
  • 引用數(shù)據(jù)類型
    • 對(duì)象數(shù)據(jù)類型object
      • {} 普通對(duì)象
      • [] 數(shù)組對(duì)象
      • /^[+-]?(\d|([1-9]\d+))(.\d+)?$/ 正則對(duì)象
      • Math數(shù)學(xué)函數(shù)對(duì)象
      • 日期對(duì)象
      • ...
    • 函數(shù)數(shù)據(jù)類型function

13-NUMBER數(shù)字?jǐn)?shù)據(jù)類型詳解

number數(shù)字類型

包含:常規(guī)數(shù)字弄诲、NaN(不是一個(gè)有效數(shù)字愚战,但它率屬于數(shù)字類型)

NaN

not a number:不是一個(gè)數(shù),但它率屬于數(shù)字類型

NaN和任何值(包括自己)都不相等:NaN!=NaN齐遵,所以我們不能用相等的方式判斷是否為有效數(shù)字

isNaN

檢測(cè)一個(gè)值是否為非有效數(shù)字寂玲,如果不是有效數(shù)字返回true,反之是有效數(shù)字返回false

// isNaN([val])  []參數(shù)描述占位符
console.log(isNaN(10)); // =>false
console.log(isNaN('AA')); // =>true
/*
 *  Number('AA') =>NaN 不能轉(zhuǎn)化為數(shù)字
 *  isNaN('AA') =>true
 */
console.log(isNaN('10')); // =>false 是有效數(shù)字
/*
 *  Number('10') =>10
 *  isNaN(10) => false
 */

isNaN底層機(jī)制:在使用isNaN進(jìn)行檢測(cè)的時(shí)候洛搀,首先會(huì)驗(yàn)證檢測(cè)的值是否為number類型敢茁,如果不是,先基于Number()這個(gè)方法留美,把值轉(zhuǎn)換為數(shù)字類型彰檬,然后再進(jìn)行檢測(cè)

把其他類型值轉(zhuǎn)換為數(shù)字類型

  • Number([val])

    把字符串轉(zhuǎn)換為數(shù)字,只要字符串中包含任意一個(gè)非有效數(shù)字字符(第一個(gè)點(diǎn)除外)谎砾,結(jié)果都是NaN逢倍。
    1)空字符串(''里面什么也沒(méi)有,沒(méi)空格)會(huì)變?yōu)閿?shù)字零;
    2)布爾值true會(huì)變成1景图,false變成0较雕;
    3)空對(duì)象指針null會(huì)變成0,未定義undefined會(huì)變成NaN挚币。
    4)把引用數(shù)據(jù)類型(包括對(duì)象包括函數(shù))轉(zhuǎn)化為數(shù)字亮蒋,是先把它基于toString方法轉(zhuǎn)化為字符串,然后再轉(zhuǎn)換為數(shù)字妆毕。
    注:
    普通對(duì)象慎玖、正則對(duì)象等結(jié)果都是NaN,只有數(shù)組的結(jié)果才可能是數(shù)字笛粘。

    一系列轉(zhuǎn)換是走的是瀏覽器底層渲染規(guī)則

    console.log(Number('12.5')); // =>12.5
    console.log(Number('12.5px')); // =>NaN
    console.log(Number('12.5.5')); // =>NaN
    console.log(Number('')); // =>0 
    console.log(Number(true)); // =>1
    
    // 布爾轉(zhuǎn)換為數(shù)字
    console.log(Number(false)); // =>0
    console.log(Number(false)); // =>0
    console.log(isNaN(false)); // =>false
    console.log(isNaN(true)); // =>false
    
    // null->0   undefined->NaN
    console.log(Number(null)); //=>0 可以這樣理解:空對(duì)象指針雖然代表沒(méi)有趁怔,但其實(shí)還是有一個(gè)東西的
    console.log(Number(undefined)); //=>NaN 可以這樣理解:undefined代表未定義,未定義代表沒(méi)有賦值薪前,沒(méi)有賦值的值就是沒(méi)有值润努,沒(méi)有值的話肯定是NaN
    
    // 把引用數(shù)據(jù)類型(包括對(duì)象包括函數(shù))轉(zhuǎn)化為數(shù)字,是先把他基于toString方法轉(zhuǎn)化為字符串示括,然后再轉(zhuǎn)換為數(shù)字
    console.log(Number({name:'10'})); // =>NaN
    console.log(Number({})); // =>NaN
    // 普通對(duì)象 {}或{xxx:'xxx'}.toString() =>"[object object]"
    console.log(Number([])); // =>0
    // [].toString -> ""
    console.log(Number([12])); // =>12
    // [12].toString() -> "12"
    console.log(Number([12,23])); // -> NaN
    // [12,23].toString() -> "12,23"
    
  • parseInt/parseFloat([val],[進(jìn)制]):也是轉(zhuǎn)換數(shù)字的方法铺浇,對(duì)于字符串來(lái)說(shuō),它是從左到右依次查找有效數(shù)字字符垛膝,直到遇到非有效數(shù)字字符随抠,停止查找(不管后面是否還有數(shù)字裁着,都不再找了),把找到的當(dāng)做數(shù)字返回

    let str = '12.5px';
    console.log(Number(str)); // =>NaN
    console.log(parseInt(str)) // =>12
    console.log(parseFloat(str)) // =>12.5
    console.log(parseFloat('width:12.5px')) // =>NaN
    parseInt("") // =>NaN (因?yàn)闆](méi)有找到有效數(shù)字,如果是Number()方法則會(huì)返回0)
    

注:
Number()拱她,parseInt/parseFloat()都是把其他類型轉(zhuǎn)換為數(shù)字類型:
1)Number()是瀏覽器內(nèi)置的一個(gè)非常重要的方法二驰,它的一系列的轉(zhuǎn)換規(guī)則,走的是瀏覽器渲染的底層規(guī)則秉沼,走的是V8引擎最底層的機(jī)制桶雀;
2)parseInt/parseFloat()是額外提供的一種方法,是處理這種字符串的唬复,如果不是字符串矗积,把它變成字符串,然后再?gòu)淖蟮接也檎页ㄟ郑荒馨炎址畯淖蟮接也檎摇?/p>

parseFloat(true); // => NaN
parseFloat('true'); // => NaN
  • ==進(jìn)行比較的時(shí)候棘捣,可能要出現(xiàn)把其它類型轉(zhuǎn)換為數(shù)字
    '10'==10 // =>true
    
  • 數(shù)學(xué)運(yùn)算
    加減乘除,除了加可能變成字符串拼接

15-string字符串?dāng)?shù)據(jù)類型詳解

string字符串?dāng)?shù)據(jù)類型

所有用單引號(hào)休建、雙引號(hào)乍恐、反引號(hào)(撇 ES6模板字符串)包起來(lái)的都是字符串

把其它類型值轉(zhuǎn)換為字符串

  • [val].toString()
  • 字符串拼接
console.log(12.toString()) // =>報(bào)錯(cuò) 實(shí)例概念
let a = 12;
console.log(a.toString()); // => '12'
console.log((NaN).toString()); // => 'NaN'   之前長(zhǎng)什么樣测砂,外面包一層引號(hào)
// null和undefined是禁止直接toString 的
(null).toString() // =>報(bào)錯(cuò) 瀏覽器的保護(hù)機(jī)制
// 但是和undefined一樣轉(zhuǎn)換為字符串的結(jié)果就是'null'/'undefined '

[].toString(); // => ""
[12].toString(); // => "12"
[12,23].toString(); // => "12,23"
/^$/.toString(); // => "/^$/"
{{name: 'xxx'}}.toString(); //=>  "[object Object]"
// 普通對(duì)象.toString()的結(jié)果是"[object Object]"
=>Object.prototype.toString方法不是轉(zhuǎn)換為字符串的茵烈,而是用來(lái)檢測(cè)數(shù)據(jù)類型的

// ============字符串拼接
// 四則運(yùn)算法則,除加法之外砌些,其余都是數(shù)學(xué)計(jì)算呜投,只有加法可能存在字符串拼接(一旦遇到字符串,則不是數(shù)學(xué)運(yùn)算存璃,而是字符串拼接)
console.log('10'+10); //=>1010
console.log('10'-10); //=>0
console.log('10px'-10); //=>NaN
// 10px用Number()轉(zhuǎn)換仑荐,NaN-10是NaN
let a = 10 + null + true + [] + undefined + '珠峰' + null + [] +10 + false;
console.log (a);
/*
 * 10 + null -> 10 + 0 -> 10
 * 10 + true -> 10 + 1 -> 11
 * 11 + [] -> 11 + '' -> '11' 空數(shù)組變?yōu)閿?shù)字,先要經(jīng)歷變?yōu)榭兆址荻龅阶址痴校抖紕e想了,直接變?yōu)樽址唇? * '11'+undefined -> '11undefined'
 * …
 * '11undefined珠峰null10false'
 */

16-boolean布爾數(shù)據(jù)類型詳解

boolean布爾數(shù)據(jù)類型

只有兩個(gè)值 true/false

把其它類型值轉(zhuǎn)換為布爾類型

只有0篮迎、NaN男图、''(空字符串)示姿、null甜橱、undefined 五個(gè)值轉(zhuǎn)換為false,其余都轉(zhuǎn)換為true(而且沒(méi)有任何的特殊情況)
V8引擎底層機(jī)制栈戳,在實(shí)現(xiàn)數(shù)據(jù)類型轉(zhuǎn)換的時(shí)候岂傲,給予的機(jī)制就是這樣的

  • Boolean([val])
// 只要不在五種情況之中,都為true
console.log(Boolean('')); // =>false
console.log(Boolean(' ')); // =>true 有空格
console.log(Boolean([])); // =>true 五種之外
console.log(Boolean([12])); // =>true
console.log(Boolean(-1)); // =>true
  • !/!!
    W犹础:取反(先轉(zhuǎn)為布爾镊掖,然后取反)
    !!:取反再取反乃戈,只相當(dāng)于轉(zhuǎn)換為布爾<=>Boolean
console.log(!1); //=>false
console.log(!!1); //=>true
  • 條件判斷
    如果條件只是一個(gè)值,不是==/===/!=/>=等這些比較亩进,是要把這個(gè)值先轉(zhuǎn)換為布爾類型症虑,然后驗(yàn)證真假
// 能輸出 哈哈
if(1) {
    console.log('哈哈');
}
// 能輸出 呵呵
if('3px'+3) {
    // => '3px3'
    console.log('呵呵');
}
// 不能輸出 嘿嘿
if('3px'-3) {
    // => NaN-3 => NaN
    console.log('嘿嘿');
}

17-null和undefined的區(qū)別

null/undefined

null和undefined都代表沒(méi)有

  • null:意料之中(一般都是開(kāi)始不知道值,我們手動(dòng)先設(shè)置為null归薛,后期再給予賦值操作)
let num = null; // =>一般最好用null作為初始的空值谍憔,因?yàn)榱悴皇强罩担跅?nèi)存中有自己的存儲(chǔ)空間(占了位置)
let num = 0; // =>有空間來(lái)存儲(chǔ)主籍,相對(duì)消耗一丟丟丟丟性能
...
num = 12;
  • undefined:意料之外(不是我能決定的)
let num; // =>創(chuàng)建一個(gè)變量沒(méi)有賦值习贫,默認(rèn)值是undefined
...
num = 12;

18-對(duì)象數(shù)據(jù)類型的基本結(jié)構(gòu)和操作

object對(duì)象數(shù)據(jù)類型-普通對(duì)象

{[key]:[value],...}
任何一個(gè)對(duì)象都是由零到多組鍵值對(duì)(屬性名:屬性值)組成的,每組鍵值對(duì)或每組屬性名和屬性值之間用逗號(hào)分隔千元;
屬性名不能重復(fù)苫昌;
屬性名只能是數(shù)字或字符串;
屬性名是數(shù)字或者字符串格式的幸海,不寫單引號(hào)雙引號(hào)默認(rèn)也是字符串格式的祟身,加上也不會(huì)有錯(cuò)誤,默認(rèn)不寫

let person = {
    name: '易烊千璽',
    age: 40,
    height: '185cm',
    weight: '80kg',
    1: 100
};
獲取屬性名對(duì)應(yīng)的屬性值(查)
  • 對(duì)象.屬性名
    屬性名是字符串的情況可用
  • 對(duì)象[屬性名]
    屬性名是數(shù)字或者字符串格式(帶引號(hào))的
console.log(person.name);
console.log(person['age']); // 不能直接寫age涕烧,屬性名是個(gè)字符串
或console.log(person["age"]); 
// =>如果當(dāng)前屬性名不存在月而,默認(rèn)的屬性值是undefined
console.log(person.sex); // =>undefined
console.log(person[1]);
// =>如果屬性名是數(shù)字,則不能使用點(diǎn)的方式獲取屬性值
// console.log(person.1); // =>SyntaxError:語(yǔ)法錯(cuò)誤
設(shè)置屬性名屬性值(改议纯、增)
person.GF = '園園';
console.log(person['GF']); // =>園園
// =>屬性名不能重復(fù)父款,如果屬性名已經(jīng)存在,不屬于新增屬于修改屬性值
person.name = '李易峰';
console.log(person['name']); // =>李易峰
刪除屬性(刪)
  • 真刪除:把屬性徹底干掉
  • 假刪除:屬性還在瞻凤,值為空
// 假刪除
person.weight = null;
console.log(person);
/*
 * 1: 100
 * age: 40
 * height: "185cm"
 * name: "易烊千璽"
 * weight: null
 */
// 真刪除
delete person[1];
console.log(person);
/*
 * age: 40
 * height: "185cm"
 * name: "易烊千璽"
 * weight: null
 */

19-數(shù)組的基本結(jié)構(gòu)(特殊對(duì)象類型)

對(duì)象數(shù)據(jù)類型object-數(shù)組對(duì)象

數(shù)組是特殊的對(duì)象數(shù)據(jù)類型
1)我們中括號(hào)中設(shè)置的是屬性值憨攒,它的屬性名是默認(rèn)生成的數(shù)字,從0開(kāi)始遞增阀参,而且這個(gè)數(shù)字代表每一項(xiàng)的位置肝集,我們把其稱為“索引”=>從零開(kāi)始連續(xù)遞增,代表每一項(xiàng)位置的數(shù)字屬性名
2)天生默認(rèn)一個(gè)屬性名length蛛壳,存儲(chǔ)數(shù)組的長(zhǎng)度

let ary = [12,'哈哈',true,13];

// 任何一個(gè)對(duì)象都必須有鍵值對(duì)(看到的是屬性值:屬性名)杏瞻,數(shù)組也是對(duì)象,它肯定也是由屬性名屬性值組成的衙荐,只不過(guò)比較特殊捞挥,寫的時(shí)候不需要寫屬性名,從0開(kāi)始逐級(jí)遞增忧吟,既是屬性名也是索引
console.log(ary);
/* [12, "哈哈", true, 13]
 * 0: 12
 * 1: "哈哈"
 * 2: true
 * 3: 13
 * length: 4
 */

// 默認(rèn)一個(gè)屬性名length
console.log(ary.length); // =>4
console.log(ary['length']); // =>4 需要寫單引號(hào) 字符串格式

/* 數(shù)組雖然是特殊對(duì)象砌函,看起來(lái)不一樣,本質(zhì)仍是對(duì)象,只要是對(duì)象讹俊,就可以使用上面的對(duì)象操作法則 */

// 輸出哈哈 哈哈索引是1
console.log(ary[1]); // =>哈哈 屬性名是數(shù)字只能用中括號(hào)方式
// 第一項(xiàng)索引是0 最后一項(xiàng)索引ary.length-1
console.log(ary[0]); //=>12
console.log(ary[ary.length-1]); //=>13

// 向數(shù)組末尾追加內(nèi)容
ary[ary.length] = 100;
console.log(ary);

20-數(shù)據(jù)類型的區(qū)別(堆棧底層機(jī)制)

let a = 12;
let b = a;
b = 13;
console.log(a); // =>12

let n = {
    name: '珠峰'
};
let m = n;
m.name = '培訓(xùn)';
console.log(n.name); // =>培訓(xùn)

瀏覽器想要執(zhí)行JS代碼:
環(huán)境垦沉、人
1)從電腦內(nèi)存當(dāng)中分配出一塊內(nèi)存,用來(lái)執(zhí)行代碼(棧內(nèi)存=>Stack)
電腦買高內(nèi)存的原因之一
2)分配一個(gè)主線程用來(lái)自上而下執(zhí)行JS代碼

上面用來(lái)存東西仍劈,下面用來(lái)執(zhí)行代碼

image.png

簡(jiǎn)單的基本類型值存儲(chǔ)

image.png
  • let a =12;
    1.創(chuàng)建變量a厕倍,放到當(dāng)前棧內(nèi)存變量存儲(chǔ)區(qū)域中
    2.創(chuàng)建一個(gè)值12,把它存儲(chǔ)到當(dāng)前棧內(nèi)存值區(qū)域中(簡(jiǎn)單的基本類型值是這樣存儲(chǔ)的贩疙,復(fù)雜的引用類型值不是這樣做的)
    3.=為賦值绑青,其實(shí)賦值是讓變量和值相互關(guān)聯(lián)的過(guò)程
  • let b = a;
    上述第1條第3條
  • b = 12;
    上述第2條第3條

復(fù)雜的引用類型值存儲(chǔ)

image.png

name屬性名已存在,屬于改

復(fù)雜值(引用類型值)的存儲(chǔ)屋群,又分成了三個(gè)步驟:
1.在內(nèi)存中分配出一塊新內(nèi)存闸婴,用來(lái)存儲(chǔ)引用類型值(堆內(nèi)存=>heap ) =>內(nèi)存有一個(gè)16進(jìn)制地址
2.把對(duì)象中的鍵值對(duì)(屬性名:屬性值)依次存儲(chǔ)到堆內(nèi)存中
3.把堆內(nèi)存地址和變量關(guān)聯(lián)起來(lái)
注意:本質(zhì)仍是遵照創(chuàng)建變量、創(chuàng)建值芍躏、關(guān)聯(lián)邪乍,三個(gè)步驟(見(jiàn)下面題)

基本數(shù)據(jù)類型、引用數(shù)據(jù)類型存儲(chǔ)對(duì)比

基本類型∶按值操作(直接操作的是值)对竣,所以也叫作值類型
引用類型∶操作的是堆內(nèi)存的地址(按引用地址操作的)庇楞,所以叫作引用數(shù)據(jù)類型

  • 基本類型值
    因?yàn)榻Y(jié)構(gòu)簡(jiǎn)單,直接存儲(chǔ)在棧內(nèi)存的值存儲(chǔ)空間當(dāng)中否纬,所有的操作是直接操作這個(gè)值
  • 引用類型值
    結(jié)構(gòu)復(fù)雜吕晌,不能直接存儲(chǔ)在值存儲(chǔ)空間中,必須開(kāi)一個(gè)堆內(nèi)存临燃,將內(nèi)容存在堆里面睛驳,然后操作的都是堆內(nèi)存的引用地址,可能會(huì)導(dǎo)致兩個(gè)變量用的都是同一個(gè)地址膜廊,管控的是同一個(gè)堆乏沸,其中一個(gè)變量把堆里的東西改了,另外一個(gè)變量受影響

21-堆棧內(nèi)存課程練習(xí)題

image.png

最底層的機(jī)制
1爪瓜、創(chuàng)建變量(先處理等號(hào)左邊)
2蹬跃、創(chuàng)建值(再處理等號(hào)右邊)
3、關(guān)聯(lián)铆铆,關(guān)聯(lián)前兩者無(wú)關(guān)(js的特點(diǎn)蝶缀,不同于某些語(yǔ)言,不是拷貝薄货,是關(guān)聯(lián))
x = [30,40]
創(chuàng)建過(guò)變量x了不用管翁都,創(chuàng)建新的值-新數(shù)組-新空間,關(guān)聯(lián)菲驴,x只能關(guān)聯(lián)一個(gè)

22-阿里的一道引發(fā)血案的面試題

// 寫出下面結(jié)果輸出的答案
let a = {
    n:1
};
let b = a;
a.x = a = {
    n:2
};
console.log(a.x);
console.log(b);

image.png

關(guān)于連等賦值:
a=b=3
從左到右
a=3
b=3
3都是一個(gè)值3荐吵,先讓a和它關(guān)聯(lián)骑冗,再讓b和它關(guān)聯(lián)赊瞬,連等賦值先煎,是讓每一個(gè)變量都和這個(gè)值關(guān)聯(lián)
a.x = a = {n:2}
1、先處理等號(hào)左邊的巧涧,看是不是要?jiǎng)?chuàng)建變量:
a.x 不是創(chuàng)建變量薯蝎,是給a設(shè)置一個(gè)屬性x
a變量已存在,不用創(chuàng)建
2谤绳、再處理等號(hào)右邊的占锯,看要不要?jiǎng)?chuàng)建值:
等號(hào)右邊是個(gè)值,需要?jiǎng)?chuàng)建值缩筛,值存儲(chǔ)空間/開(kāi)個(gè)堆
等號(hào)右邊是引用類型消略,開(kāi)個(gè)堆,AAAFFF111
3瞎抛、關(guān)聯(lián)
先讓a.x和值關(guān)聯(lián)艺演,之前沒(méi)有x這個(gè)屬性名,新增桐臊,x和AAAFFF111關(guān)聯(lián)
再讓a和AAAFFF111關(guān)聯(lián)

// 變形
let a = {
    n:1
};
let b = a;
a.x = b;

無(wú)限次嵌套胎撤,堆的嵌套,內(nèi)存嵌套断凶,導(dǎo)致內(nèi)存無(wú)限溢出


image.png

23-數(shù)據(jù)類型檢測(cè)

JS中的數(shù)據(jù)類型檢測(cè)

  • typeof [val]:用來(lái)檢測(cè)數(shù)據(jù)類型的運(yùn)算符
  • instanceof:用來(lái)檢測(cè)當(dāng)前實(shí)例是否率屬于某個(gè)類
  • constructor:基于構(gòu)造函數(shù)檢測(cè)數(shù)據(jù)類型(也是基于類的方式)
  • Object.prototype.toString.call():檢測(cè)數(shù)據(jù)類型最好的辦法

注:
1伤提、前三個(gè)都有不足,第四個(gè)沒(méi)有认烁,做輕量級(jí)檢測(cè)的時(shí)候肿男,前三個(gè)能處理某些事,就不用第四個(gè)了
2却嗡、
typeof 次伶,運(yùn)算符,不是方法稽穆;
instanceof冠王,運(yùn)算符,不是方法舌镶;
constructor柱彻,屬性,不是方法餐胀,但是constructor構(gòu)造函數(shù)也可以當(dāng)作方法哟楷;
運(yùn)算符如 1 + 1中的+
方法如sum()
所以typeof運(yùn)算符后面直接加value值,不加()執(zhí)行

typeof

基于typeof檢測(cè)出來(lái)的結(jié)果
1否灾、首先是一個(gè)字符串
2卖擅、字符串中包含對(duì)應(yīng)的類型
局限性
1、typeof null => "object" 但是null并不是對(duì)象
2、基于typeof無(wú)法細(xì)分出當(dāng)前值是普通對(duì)象還是數(shù)組對(duì)象等惩阶,因?yàn)橹灰菍?duì)象數(shù)據(jù)類型挎狸,返回的結(jié)果都是"object"

image.png

image.png

console.log(typeof 1); // =>number (控制臺(tái)打出來(lái)的是黑色字體的number,默認(rèn)省略""断楷,但控制臺(tái)其實(shí)是有顏色區(qū)分的锨匆,黑色代表是字符串,藍(lán)色是數(shù)字冬筒,直接在控制臺(tái)typeof 1更加明顯恐锣,是"number")
let a = NaN;
console.log(typeof a); //=>'number'
console.log(1);
console.log(typeof typeof typeof []); 
// 從和值最近的開(kāi)始,先靠近值的先運(yùn)算舞痰,從右到左
// =>typeof [] => "object"
// =>typeof "object" => "string"
// 因?yàn)閠ypeof檢測(cè)的結(jié)果是字符串土榴,只要兩個(gè)及兩個(gè)以上同時(shí)檢測(cè),最后結(jié)果必然是"string"
答案是"string" 加雙引號(hào)或單引號(hào)响牛,注意細(xì)節(jié)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鞭衩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子娃善,更是在濱河造成了極大的恐慌论衍,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聚磺,死亡現(xiàn)場(chǎng)離奇詭異坯台,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)瘫寝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蜒蕾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人焕阿,你說(shuō)我怎么就攤上這事咪啡。” “怎么了暮屡?”我有些...
    開(kāi)封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵撤摸,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我褒纲,道長(zhǎng)准夷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任莺掠,我火速辦了婚禮衫嵌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘彻秆。我一直安慰自己楔绞,他們只是感情好结闸,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著酒朵,像睡著了一般桦锄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耻讽,一...
    開(kāi)封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音帕棉,去河邊找鬼针肥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛香伴,可吹牛的內(nèi)容都是我干的慰枕。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼即纲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼具帮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起低斋,我...
    開(kāi)封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蜂厅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后膊畴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掘猿,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年唇跨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稠通。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡买猖,死狀恐怖改橘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玉控,我是刑警寧澤飞主,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站高诺,受9級(jí)特大地震影響既棺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜懒叛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一丸冕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薛窥,春花似錦胖烛、人聲如沸眼姐。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)众旗。三九已至,卻和暖如春趟畏,著一層夾襖步出監(jiān)牢的瞬間贡歧,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工赋秀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留利朵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓猎莲,卻偏偏與公主長(zhǎng)得像绍弟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子著洼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容