JavaScript数据类型

02-JavaScript-内部JS、外部JS、数据类型、关键词 内部JS示例");// 在页面加载完成后自动弹出提示框 阅读详情

数据类型

1.JavaScript有哪些数据类型,它们的区别?

JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。

其中 Symbol 和 BigInt 是ES6 中新增的数据类型:
● Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。
● BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。

这些数据可以分为原始数据类型和引用数据类型:
● 栈:原始数据类型(Undefined、Null、Boolean、Number、String、Symbol、BigInt)
● 堆:引用数据类型(对象、数组和函数)

基本数据类型的修改实际上是新申请一块内存地址,将这个指针指向新的内存地址。使用const定义变量,实际上相当于定义了一个指针常量,指向固定的地址不能被修改。

引用类型修改时相当于前拷贝,内存地址不发生变化

引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何操作都会相互影响

var a ={};
var b = a;
a.name = 'Mary';
console.log(a.name); //'Mary'
console.log(b.name);//'Mary'
 
b.age = 22;
console.log(b.age); //22
console.log(a.age); //22
console,.log(a==b);  //true

在这里插入图片描述
两种类型的区别在于存储位置的不同:
● 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
● 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

堆和栈的概念存在于数据结构和操作系统内存中,在数据结构中:
● 在数据结构中,栈中数据的存取方式为先进后出。
● 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。

在操作系统中,内存被分为栈区和堆区:
● 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
● 堆区内存一般由开发着分配释放,若开发者不释放,程序结束时可能由垃圾回收机制回收。

2. 数据类型检测的方式有哪些

(1)typeof

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object    
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object

其中数组、对象、null都会被判断为object,其他判断都正确。

(2)instanceof

instanceof可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

instanceof只能正确判断引用数据类型,而不能判断基本数据类型。

(3) constructor

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

constructor有两个作用,一是判断数据的类型,二是对象实例通过 constrcutor 对象访问它的构造函数。需要注意,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了:

function Fn(){};
 
Fn.prototype = new Array();
 
var f = new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true

(4)Object.prototype.toString.call()

Object.prototype.toString.call() 使用 Object 对象的原型方法 toString 来判断数据类型:

var a = Object.prototype.toString;
 
console.log(a.call(2));
console.log(a.call(true));
console.log(a.call('str'));
console.log(a.call([]));
console.log(a.call(function(){}));
console.log(a.call({}));
console.log(a.call(undefined));
console.log(a.call(null));

同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样

  console.log(function () {}.toString());
  //function () {}
  

这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

3. 判断数组的方式有哪些

● 通过Object.prototype.toString.call()做判断

 <script>
      function fn() {
        console.log("11");
      }
      console.log(Object.prototype.toString.call(fn)); //”[object Function]”);//”[object Function]”
	
      var obj = [1, 2, 3];
      //通过Object.prototype.toString.call()做判断
      console.log(Object.prototype.toString.call(obj).slice(8, -1) === "Array"); //true
      //通过原型链做判断
      console.log(obj.__proto__ === Array.prototype);//true
      //通过ES6的Array.isArray()做判断
      console.log(Array.isArray(obj));//true
      //通过instanceof做判断
      console.log(obj instanceof Array);//true
      //通过Array.prototype.isPrototypeOf
      console.log(Array.prototype.isPrototypeOf(obj));//true
    </script>

4. null和undefined区别

1、概念

undefined 表示未定义,就是应该有值但是还没有赋值,连null的值都没有赋予

null 代表空值,空引用。

2、区别

  1. null 和 undefined 虽然值的结果是相等的,但是其所代表的语义是完全不一样的(==是相等的)。

undefined 代表了某个变量完全不存在,在内存中完全能不存在这个标识符所指向的地址;

null 代表了内存中是存在这个变量的,只是我在某些情况下需要把这个变量原本的值给覆盖了,将它设置为一个空。

  1. null 转为数值是 0 ; undefined 转为数值是 NAN(not a number)。

  2. null 通过 typeof 判断类型的时候结果的输出是 object ; 而 undefined 的类型是 undefined 。

那么为什么 typeof null 是 object ?

null 和 undefined 都是js语言的基础数据类型, 都是原始值类型,但是 typeof null 是 object ,是因为不同的对象在底层都表现为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,null 的二进制全部都为 0 ,前三位自然也是 0 ,所以执行 typeof 值会返回 object 。

  1. null 是 js 语言的关键字,是不允许用户用来作为标识符声明变量的,但是 undefined 可以,undefined 不是关键字。

在 node 环境中,我们声明的 undefined 会将原本的 undefined 覆盖的,但是在浏览器环境中不会,是因为浏览器中的 undefined 是直接被使用 Object.defineProperty 定义在了全局对象 window 上,默认就已经被配置成为了:值不可修改并且不可以被重新进行配置。

3、null 和 undefined分别在实际项目中出现的场景有哪些

1、 undefined

a. 变量被声明了,但是没有被赋值;

b. 调用函数的时候,应该给函数传参却没有给函数传这个参数打印出来就是 undefined;

c. 访问一个对象中没有的属性;

d. 函数没有返回值时,默认就会返回undefined。

2、 null

a.作为对象原型链的终点出现;

b.当我们访问一个不存在的dom节点的时候。

5. typeof null 的结果是什么,为什么?

typeof null 的结果是Object。

javascript中不同对象在底层都表示为二进制,而javascript 中把二进制前三位都为0的判断为object类型,而null的二进制表示全都是0,自然前三位也是0,所以执行typeof时会返回’object’

在 JavaScript 第一个版本中,所有值都存储在 32 位的单元中,每个单元包含一个小的 类型标签(1-3 bits) 以及当前要存储值的真实数据。类型标签存储在每个单元的低位中,共有五种数据类型:

000: object   - 当前存储的数据指向一个对象。
  1: int      - 当前存储的数据是一个 31 位的有符号整数。
010: double   - 当前存储的数据指向一个双精度的浮点数。
100: string   - 当前存储的数据指向一个字符串。
110: boolean  - 当前存储的数据是布尔值。

如果最低位是 1,则类型标签标志位的长度只有一位;如果最低位是 0,则类型标签标志位的长度占三位,为存储其他四种数据类型提供了额外两个 bit 的长度。

有两种特殊数据类型:
● undefined的值是 (-2)30(一个超出整数范围的数字);
● null 的值是机器码 NULL 指针(null 指针的值全是 0)

那也就是说null的类型标签也是000,和Object的类型标签一样,所以会被判定为Object。

6. intanceof 操作符的实现原理及实现

instanceof 运算符用于判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。

function myInstanceof(left, right) {
  // 获取对象的原型
  let proto = Object.getPrototypeOf(left)
  // 获取构造函数的 prototype 对象
  let prototype = right.prototype; 
 
  // 判断构造函数的 prototype 对象是否在对象的原型链上
  while (true) {
    if (!proto) return false;
    if (proto === prototype) return true;
    // 如果没有找到,就继续从其原型上找,Object.getPrototypeOf方法用来获取指定对象的原型
    proto = Object.getPrototypeOf(proto);
  }
}

7. 为什么0.1+0.2 ! == 0.3,如何让其相等

<script>
      let n1 = 0.1,
        n2 = 0.2;
      console.log(n1 + n2); // 0.30000000000000004
      console.log((n1 + n2).toFixed(2)); // 注意,toFixed为四舍五入
    </script>

计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实际上是计算的两个数的二进制的和。0.1的二进制是0.0001100110011001100…(1100循环),0.2的二进制是:0.00110011001100…(1100循环),这两个数的二进制都是无限循环的数。那JavaScript是如何处理无限循环的二进制小数呢?

一般我们认为数字包括整数和小数,但是在 JavaScript 中只有一种数字类型:Number,它的实现遵循IEEE 754标准,使用64位固定长度来表示,也就是标准的double双精度浮点数。在二进制科学表示法中,双精度浮点数的小数部分最多只能保留52位,再加上前面的1,其实就是保留53位有效数字,剩余的需要舍去,遵从“0舍1入”的原则。

根据这个原则,0.1和0.2的二进制数相加,再转化为十进制数就是:0.30000000000000004。

下面看一下双精度数是如何保存的:

● 第一部分(蓝色):用来存储符号位(sign),用来区分正负数,0表示正数,占用1位
● 第二部分(绿色):用来存储指数(exponent),占用11位
● 第三部分(红色):用来存储小数(fraction),占用52位

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3

function numberepsilon(arg1,arg2){                   
  return Math.abs(arg1 - arg2) < Number.EPSILON;        
}        

console.log(numberepsilon(0.1 + 0.2, 0.3)); // true

8. 如何获取安全的 undefined 值?

因为 undefined 是一个标识符,所以可以被当作变量来使用和赋值,但是这样会影响 undefined 的正常判断。表达式 void ___ 没有返回值,因此返回结果是 undefined。void 并不改变表达式的结果,只是让表达式不返回值。因此可以用 void 0 来获得 undefined。

9. typeof NaN 的结果是什么?

NaN 指“不是一个数字”(not a number),NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果

typeof NaN; // "number"

NaN 是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即 x === x 不成立)的值。而 NaN !== NaN 为 true。

10.isNaN 和 Number.isNaN 函数的区别

NaN
NaN意指“not a number“,是一个“警戒值”,用于指出数字类型中的错误情况。
typeof NaN的返回值是”number“。
NaN是一个特殊值,它与自身不相等,是唯一一个非自反的值。即 NaN === NaN 返回false,NaN !== NaN 返回true。
因此,我们不能简单地通过 == 或者=== 运算符来判断数值是否非法数值,我们需要 isNaN() 或者 Number.isNaN() 两个函数进行判断。

typeof NaN   // "number"
NaN === NaN  // false
NaN !== NaN  // true

isNaN()
isNaN() 函数接收一个参数x,用来检查x是否非数字值。
isNaN() 函数接收参数x之后,会先把参数x转换为数字类型,任何非数字类型的值都会被强制转换为NaN,再做判断。
因此,isNaN() 函数的参数是NaN或者其他能够被转换为NaN的值时,结果都会返回true,其他值的情况下返回false。
故,isNaN() 函数会影响NaN的准确判断。

isNaN(null)   // false  Number(null) => 0
isNaN(undefined)   // true  Number(undefined) => NaN
isNaN(1)      // false
isNaN(' ')    // false  Number(' ') => 0
isNaN('1')    // false  Number('1') => 1
isNaN('abc')  // true   Number('abc') => NaN
isNaN('NaN')  // true   Number('NaN') => NaN
isNaN([])     // false  Number([]) => 0
isNaN([1])    // false  Number([1]) => 1
isNaN(['a'])  // true   Number(['a']) => NaN
isNaN({})	  // true   Number({}) => NaN
isNaN('2021/5/22')  // true  Number('2021/5/21') => NaN
isNaN(0 / 0)  // true
isNaN(NaN)    // true

Number.isNaN()
Number.isNaN() 函数也是接收一个参数x,判断x是否非数字值。
Number.isNaN() 函数在接收参数x之后,会首先判断参数x是否为数字类型,如果是数字类型则继续判断是否NaN。
因此,Number.isNaN() 相比全局函数 isNaN() 更为精准,只有在参数x本身为NaN的情况下才会返回true。

// 只有参数本身为NaN结果才为true
Number.isNaN(NaN)    // true
Number.isNaN(Number.NaN)   // true
Number.isNaN(0 / 0)  // true

// 以下在全局isNaN()函数的结果都为true,在Number.isNaN()结果都为false
isNaN(undefined)   // false
isNaN('abc')  // false
isNaN('NaN')  // false
isNaN(['a'])  // false
isNaN({})	  // false
isNaN('2021/5/22')  // false

// 以下仍然为false
isNaN(null)   // false
isNaN(1)      // false
isNaN(' ')    // false
isNaN('1')    // false
isNaN([])     // false
isNaN([1])    // false

11. == 操作符的强制类型转换规则?

在这里插入图片描述
对于 == 来说,如果对比双方的类型不一样,就会进行类型转换。假如对比 x 和 y 是否相同,就会进行如下判断流程:

  1. 首先会判断两者类型是否相同,相同的话就比较两者的大小;
  2. 类型不相同的话,就会进行类型转换;
  3. 会先判断是否在对比 null 和 undefined,是的话就会返回 true
  4. 判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number
1 == '1'
      ↓
1 ==  1
  1. 判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断
'1' == true
        ↓
'1' ==  1
        ↓
 1  ==  1
  1. 判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断
'1' == { name: 'js' }
        ↓
'1' == '[object Object]'  

12. 其他值到字符串的转换规则?

● Null 和 Undefined 类型 ,null 转换为 “null”,undefined 转换为 “undefined”,
● Boolean 类型,true 转换为 “true”,false 转换为 “false”。
● Number 类型的值直接转换,不过那些极小和极大的数字会使用指数形式。
● Symbol 类型的值直接转换,但是只允许显式强制类型转换,使用隐式强制类型转换会产生错误。
● 对普通对象来说,除非自行定义 toString() 方法,否则会调用 toString()(Object.prototype.toString())来返回内部属性 [[Class]] 的值,如"[object Object]"。如果对象有自己的 toString() 方法,字符串化时就会调用该方法并使用其返回值。

13. 其他值到数字值的转换规则?

● Undefined 类型的值转换为 NaN。
● Null 类型的值转换为 0。
● Boolean 类型的值,true 转换为 1,false 转换为 0。
● String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。
● Symbol 类型的值不能转换为数字,会报错。
● 对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。

为了将值转换为相应的基本类型值,抽象操作 ToPrimitive 会首先(通过内部操作 DefaultValue)检查该值是否有valueOf()方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。

如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。

14. 其他值到布尔类型的值的转换规则?

以下这些是假值:
• undefined
• null
• false
• +0、-0 和 NaN
• “”

假值的布尔强制类型转换结果为 false。从逻辑上说,假值列表以外的都应该是真值。

15. || 和 && 操作符的返回值?

|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先强制转换为布尔类型,然后再执行条件判断。

● 对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。
● && 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。

|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果

在js中&&运算符优先级大于||

a || b:

如果a是true,那么b不管是true还是false,都返回true。因此不用判断b了,这个时候刚好判断到a,因此返回a。
如果a是false,那么就要判断b,如果b是true,那么返回true,如果b是false,返回false,其实不就是返回b了吗。

a && b:

如果a是false,那么b不管是true还是false,都返回false,因此不用判断b了,这个时候刚好判断到a,因此返回a。
如果a是true,那么就要在判断b,和刚刚一样,不管b是true是false,都返回b。

      let a = true;
      let b = true;
      console.log(a && b);
      console.log(a || b);
 <script>
      console.log(false || 1); //1
      console.log(false || 0); //0
      console.log(true || 0); //true
      console.log(true || 1); ////true
      console.log(true == 1); //true
      console.log(true == 0); //false

      //   console.log(false && 1); //false
      //   console.log(false && 0); //false
      //   console.log(true && 0); //0
      //   console.log(true && 1); //1
      //   console.log(true == 1); //true
      //   console.log(true == 0); //false
    </script>

16. Object.is() 与比较操作符 “=”、“” 的区别?

● 使用双等号()进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。
● 使用三等号(
=)进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false。
● 使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 是相等的。

      console.log(-0 === +0); //true
      console.log(NaN === NaN); //false

      console.log(Object.is(-0, +0)); //false
      console.log(Object.is(NaN, +NaN));//true

17. 什么是 JavaScript 中的包装类型?

在 JavaScript 中,基本类型是没有属性和方法的,但是为了便于操作基本类型的值,在调用基本类型的属性或方法时 JavaScript 会在后台隐式地将基本类型的值转换为对象,如:

const a = "abc";
a.length; // 3
a.toUpperCase(); // "ABC"

在访问’abc’.length时,JavaScript 将’abc’在后台转换成String(‘abc’),然后再访问其length属性。

JavaScript也可以使用Object函数显式地将基本类型转换为包装类型:

var a = 'abc'
Object(a) // String {"abc"}

也可以使用valueOf方法将包装类型倒转成基本类型:

var a = 'abc'
var b = Object(a)
var c = b.valueOf() // 'abc'

看看如下代码会打印出什么:

var a = new Boolean( false );
if (!a) {
	console.log( "Oops" ); // never runs
}

包装类返回的是一个对象

答案是什么都不会打印,因为虽然包裹的基本类型是false,但是false被包裹成包装类型后就成了对象,所以其非值为false,所以循环体中的内容不会运行。

18. JavaScript 中如何进行隐式类型转换?

首先要介绍ToPrimitive方法,这是 JavaScript 中每个值隐含的自带的方法,用来将值 (无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接返回值本身;如果值为对象,其看起来大概是这样:

/**
* @obj 需要转换的对象
* @type 期望的结果类型
*/
ToPrimitive(obj,type)

type的值为number或者string。
(1)当type为number时规则如下:
● 调用obj的valueOf方法,如果为原始值,则返回,否则下一步;
● 调用obj的toString方法,后续同上;
● 抛出TypeError 异常。
(2)当type为string时规则如下:
● 调用obj的toString方法,如果为原始值,则返回,否则下一步;
● 调用obj的valueOf方法,后续同上;
● 抛出TypeError 异常。

可以看出两者的主要区别在于调用toString和valueOf的先后顺序。默认情况下:
● 如果对象为 Date 对象,则type默认为string;
● 其他情况下,type默认为number。
总结上面的规则,对于 Date 以外的对象,转换为基本类型的大概规则可以概括为一个函数:

var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN

而 JavaScript 中的隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive转换成基本类型,再进行操作。

以下是基本类型的值在不同操作符的情况下隐式转换的规则 (对于对象,其会被ToPrimitive转换成基本类型,所以最终还是要应用基本类型转换规则):

  1. +操作符+操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。
1 + '23' // '123'
 1 + false // 1 
 1 + Symbol() // Uncaught TypeError: Cannot convert a Symbol value to a number
 '1' + false // '1false'
 false + true // 1
  1. -、*、\操作符NaN也是一个数字
1 * '23' // 23
 1 * false // 0
 1 / 'aa' // NaN
  1. 对于==操作符
    操作符两边的值都尽量转成number:
3 == true // false, 3 转为number为3,true转为number为1
'0' == false //true, '0'转为number为0,false转为number为0
'0' == 0 // '0'转为number为0
  1. 对于<和>比较符
'ca' < 'bd' // false
'a' < 'b' // true

其他情况下,转换为数字再比较:

'12' < 13 // true
false > -1 // true

以上说的是基本类型的隐式转换,而对象会被ToPrimitive转换为基本类型再进行转换:

var a = {}
a > 2 // false

其对比过程如下:

a.valueOf() // {}, 上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]",现在是一个字符串了
Number(a.toString()) // NaN,根据上面 < 和 > 操作符的规则,要转换成数字
NaN > 2 //false,得出比较结果

又比如:

var a = {name:'Jack'}
var b = {age: 18}
a + b // "[object Object][object Object]"

运算过程如下:

a.valueOf() // {},上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]"
b.valueOf() // 同理
b.toString() // "[object Object]"
a + b // "[object Object][object Object]"

19. + 操作符什么时候用于字符串的拼接?

根据 ES5 规范,如果某个操作数是字符串或者能够通过以下步骤转换为字符串的话,+ 将进行拼接操作。如果其中一个操作数是对象(包括数组),则首先对其调用 ToPrimitive 抽象操作,该抽象操作再调用 [[DefaultValue]],以数字作为上下文。如果不能转换为字符串,则会将其转换为数字类型来进行计算。

简单来说就是,如果 + 的其中一个操作数是字符串(或者通过以上步骤最终得到字符串),则执行字符串拼接,否则执行数字加法。

那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字。

20. 为什么会有BigInt的提案?

JavaScript中Number.MAX_SAFE_INTEGER表示最⼤安全数字,计算结果是9007199254740991,即在这个数范围内不会出现精度丢失(⼩数除外)。但是⼀旦超过这个范围,js就会出现计算不准确的情况,这在⼤数计算的时候不得不依靠⼀些第三⽅库进⾏解决,因此官⽅提出了BigInt来解决此问题。

21. object.assign和扩展运算法是深拷贝还是浅拷贝,两者区别

扩展运算符:

let outObj = {
  inObj: {a: 1, b: 2}
}
let newObj = {...outObj}
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}

Object.assign():

let outObj = {
  inObj: {a: 1, b: 2}
}
let newObj = Object.assign({}, outObj)
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}

可以看到,两者都是浅拷贝。
● Object.assign()方法接收的第一个参数作为目标对象,后面的所有参数作为源对象。然后把所有的源对象合并到目标对象中。它会修改了一个对象,因此会触发 ES6 setter。
● 扩展操作符(…)使用它时,数组或对象中的每一个值都会被拷贝到一个新的数组或对象中。它不复制继承的属性或类的属性,但是它会复制ES6的 symbols 属性。

22. 如何判断一个对象是空对象

使用JSON自带的.stringify方法来判断:

if(Json.stringify(Obj) == '{}' ){
    console.log('空对象');
}

使用ES6新增的方法Object.keys()来判断:

if(Object.keys(Obj).length < 0){
    console.log('空对象');
}
超过4.2万个AOI(地理围栏),深圳市2025年2月15日更新的全类别AOI,矢量图层(全国22个超大特大城市AOI更新系列) 阅读详情

相关推荐

逆向解析喜马拉雅新版xm-sign算法:从dws.1.6.8.js到签名生成

本文详细解析了喜马拉雅新版xm-sign算法的逆向破解方法。通过定位核心JS文件dws.1.6.8.js,构建本地Node.js模拟执行环境,并解密关键参数cid与appKey,最终实现签名算法的本地化稳定生成,为数据采集提供可靠解决方案。

weixin_29250403的博客 211

toString函数的重写(JavaScript)

当我们在页面上直接打印一个对象的时候他的结果都是[object Object],其实我们直接打印对象的时候其实打印的是对象toString方法的返回值,对象的toString方法返回值就是[object Object] 我们可以重写toString方法,让我们在直接打印对象的时候会显示不同的效果 因为原对象的toString方法是在对象的原型对象的原型对象里面的,所以我们在这个外边写一个toString函数直接覆盖掉原来的toString函数 我们直接为构造函数(类)的原型对象写一个toString函数,

你好牛蛙! 1508

基于Xilinx的I2S Receiver IP核和I2S Transmitter IP核音频验证

基于Xilinx的I2S Receiver IP核和I2S Transmitter IP核音频验证 文章目录前言一、工程构架二、Xilinx IP的配置1.I2S Transmitter IP配置:2.I2S Receiver IP配置:3.WM8960的配置:总结 前言 本实验基于Xilinx ZU4EV平台,也适用于ZYNQ平台。音频验证完成,记录调过程。 ①Xilinx 音频IP只支持主模式,左对齐或右对齐方式,16bit或24bit字长。 ②WM8960器件作为从模式;24bit字长;数据传输格

weixin_45637597的博客 6814

牛客最新前端JS笔试百题

大家好,我是 漫步,分享一篇比较全的面试题,包含单选、多选和笔试题。喜欢记得关注我并设为星标。前言面经部分题目传送门: 牛客最新前端面经面试题汇总(含解析)[1]前几天空闲时间抓取了牛客最...

前端开发博客 1789

本地大模型部署实战:LM Studio与Ollama的易用性与性能深度评测

本文对两款主流本地大模型部署工具LM Studio和Ollama进行了深度评测。LM Studio凭借图形化界面和内置模型库,为新手提供了开箱即用的便捷体验,并支持OpenAI兼容API,易于生态集成。Ollama则以命令行驱动,轻量高效,凭借其原生API和Modelfile自定义能力,在自动化集成和性能方面表现突出。文章从易用性、模型生态、性能及扩展性多维度对比,帮助用户根据自身技术背景和使用场景做出最佳选择。

weixin_29039773的博客 528

PYTHON 打印三角形大全

用PYTHON语言打印各种三角形

世上无难事,只要肯攀登 1万+

JavaScript 对象转换之 toString 和 valueOf

开始这个话题之前,我们先看一下下面的几个例子: parseInt(0.0000004) // 4 ![]==[] //true ['x','y'] == 'x,y' //true alert({name:'mofei'}) //"[object Object]" 结果有时候会让我大吃一惊,这是为什么呢?今天就和大家讨论一下JavaScript的对象转换。 基础类型 先让我们

新博客地址:blog.songchunmin.com 1126

DETRs with Collaborative Hybrid Assignments Training论文阅读与代码

在这篇论文中,作者观察到在DETR中将过少的 Query 分配为正样本,采用一对一的集合匹配,会导致对编码器输出的监督稀疏,严重损害编码器的区分特征学习,反之亦然,也会影响解码器中的注意力学习。为了缓解这个问题,作者提出了一种新颖的协同混合分配训练方案,名为Co-DETR,以从多样的标签分配方式中学习更高效、更有效的基于DETR的检测器。这种新的训练方案可以通过训练多个并行辅助 Head ,以一对多的标签分配方式(如ATSS和Faster RCNN)进行监督,轻松增强端到端检测器中编码器的学习能力。

qingjing0413的博客 1154

JS重写Object的toString()方法

1. 起因:JSON.stringify方法转换成的字符串为JSON格式,属性名带有双引号,input输入框提交时报错。原因待确认。2. &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;&lt;/title&gt; &lt;/head&

guoxiaozhuang4的博客 5326

Source Insight 4.0舒适黑主题 仿心情看的舒服就行

Source Insight 4.0主题 仿心情看的舒服就行 source insight自带的主题怎么看怎么别扭,于是在试用全网各种主题配色后,在其中一个基础上自定义了c/c++的语法配色 截全图有点糊 函数定义 全局变量 局部变量 枚举变量引用 全局变量引用及结构体成员 宏定义引用 ----------------------后面会再把主题文件贴上来-------------- ...

weixin_43443402的博客 1303

别再为SCI论文配图发愁了!手把手教你用PS+AI搞定从数据图到模式图的全流程

本文详细解析了如何利用Photoshop(PS)和Illustrator(AI)高效完成SCI论文配图的全流程,涵盖数据可视化、模式图设计及期刊适配性输出。通过实战案例,帮助科研人员掌握位图与矢量图的处理技巧,提升论文配图质量,满足不同期刊的出版要求。

weixin_28630185的博客 382

重写 toString()和Object.prototype.toString()的不同

首先记住undefined , null没有toString()方法. 大家都知道toString()是用来返回相对应类型值的字符串格式. 当我们调用toString()返回发现结果并非如此, 当我们对Number,String,Boolean,Array类型 调用 toString()方法时,会返回想对应的字符串. var arr= [1,2] arr.toString() //"1,2" va...

weixin_43936704的博客 321

C#里用HttpListener实现WEB API接口服务端

本文介绍了一个基于WinForm的HTTP服务实现方案。该方案使用HttpListener类创建了一个支持JSON POST请求处理的轻量级Web服务器,主要特点包括:1) 纯线程方式实现请求监听和处理;2) 提供标准化的JSON响应格式;3) 支持自定义请求处理逻辑;4) 包含完整的日志记录功能。代码示例展示了如何初始化服务、处理不同类型的请求(包括JSON POST),并提供了线程安全的UI更新机制。该实现适用于需要简单HTTP接口的Windows桌面应用程序,可作为程序间通信的基础设施。

大坡3D软件开发 228

【JavaScript】一篇文章,带你拿捏JS中的数据类型

JavaScript有8种数据类型:7种基本类型(String、Number、Boolean、null、undefined、Symbol、BigInt)和引用类型Object。基本类型存储在栈内存中,引用类型存储在堆内存中,栈中保存引用地址。字符串不可变,数组可变;数字采用IEEE754标准,存在精度问题;布尔值用于逻辑运算;null表示空值,undefined表示未赋值;Symbol创建唯一标识符;BigInt处理大整数。引用类型包括对象、数组、函数等。内存分为代码空间(存储代码)、栈空间(存储基本类型和

sunshine_dd的博客 1479

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【JavaScript】(二) JS数据类型

目录数据类型1、数据类型简介1.1 变量的数据类型1.2 数据类型的分类2、 简单数据类型2.1 基本数据类型2.2 数字型 Number2.2.1 数字型进制2.2.2 数字型范围2.2.3 数字型三个特殊值2.2.4 isNaN()2.3 字符串型 String2.3.1 字符串引号嵌套2.3.2 字符串转义符2.3.3 字符串长度2.3.4 字符串拼接2.3.5 字符串拼接加强2.4 布尔型 Boolean2.5 Undefined 和 Null3、 获取变量数据类型3.1 获取检测变量的数据.

weixin_48650082的博客 2079

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【JavaScript用法】JavaScript(JS)的基本语法(JS数据类型,JS变量,JS运算符,JS流程控制语句)

JavaScript(JS)的基本语法 目录 JavaScript(JS)的基本语法 一. 与html结合方式 二. 注释 三. 数据类型: 四. 变量 五. 运算符(和Java有点类似) 六. 流程控制语句(和JAVA类似): 七. JS特殊语法: 一. 与html结合方式 1. 内部JS:定义<script>,标签体内容就是js代码(...

No8g攻城狮的博客 5105

JS学习篇(二) JavaScript七种数据类型

要了解一门语言,首先要了解它的数据类型有哪些?他们之间有什么关系?能否互相转换等。 目前,JavaScript(下称JS)中有七大数据类型,它们分别是: 1. Boolean 布尔型 2. Null 空 3. Undefined 未定义 4. Number 数字型 5. String 字符串型 ...

豪阁的个人博客 1852

JavaScript数据类型和转化——JS

目录 1.数据类型 1.1为什么需要数据类型 1.2变量的数据类型 1.3数据类型分类 2.模板字符串(ES6新增),——模板字面量 2.1解析变量 2.2字符串可以换行 2.3调用函数 3.typeof和字面量 3.1typeof的使用 3.2字面量 4.数据类型的转换 4.1什么是数据类型 4.2转换为字符串类型 4.3转换为数字型 4.4转换为布尔型 1.数据类型 1.1为什么需要数据类型 因为不同数据所占用的存储空间不同,为了便于把数据分成所需内存大小

孙宇航的博客 1227

JavaScript系列-07 JS数据类型之undefined类型

javaScript系列 JS的数据类型 文章目录javaScript系列前言一、undefined数据类型1.1简单了解 前言 虽然js在变量声明的时候无需指定数据类型,但是在赋值的时候,每个数据还是有属于自己的数据类型。所以还是有了解的必要 一、undefined数据类型 1.1简单了解 Undefined类型只有一个值,这个值就是 undefined 当一个变量没有手动赋值,系统默认赋值undefined 或者也可以给一个变量手动赋值undefined。 <script typ

m0_46222379的博客 252

JavaScript 学习手册二:JS 数据类型

第1关:JavaScript 数据类型介绍 任务描述 本关任务:在函数 objectTest() 内部定义了六个变量 a、b、c、d、e、f,并已经赋值,你需要判断它们各是什么数据类型。变量 aType、bType、cType、dType、eType、fType 分别表示上面六个变量的数据类型的名字,你需要给他们赋值。比如变量 a 如果是数字类型,需要给变量 aType 赋值字符串 number。可选的数据类型名如下: number、string、bool、object、undefined 和 arra

weixin_54327001的博客 8432

【Js】JavaScript数据类型隐式转换

类型相同基本类型,直接比较值引用类型比较指针类型不同,尝试转成number类型,先调用valueOf()转成number不行就再用toString()方法转成stringnull、NaN、undefined单独一套规则。

m0_57135756的博客 1万+

【JavaScript基础】JS中的数据类型

基本数据类型 Js中的基本数据类型有五种:Undefined、Null、Boolean、Number、String 1. Undefined Undefined类型只有undefined一个值,在使用var声明变量但是未进行初始化的时候,该变量的值就是undefined。 2. Null Null类型也同样只有null一个值,表示一个空对象指针。undefined其实也是派生自null值的,但是null和undefined的含义完全不同。 3. Boolean Boolean类型有true和false两个值

VoidD的博客 312

JS初识 JavaScript变量 数据类型

变量作用域:分为全局作用域和局部作用域,函数外部和函数内部使用var声明的变量写在函数内部就是局部变量 仅当前作用域可见,声明在函数外部的变量就是全局变量 所有作用域可见,写在函数内部但是前面不加声明变量关键字就是全局变量。值类型(基本数据类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol(唯一)、bigInt(+n)。注释、变量、操作符、流程控制语句、数组、对象、函数....的轻量级,解释型或即时编译型的编程语言。

qq_53402777的博客 334

Js高级总结1 JavaScript数据类型

typeof:返回数据类型的字符串表达,可以判断 undefined 数值 字符串 布尔值 function,不能判断 null object array。test.call/apply(obj):obj.test(),让一个函数成为任意指定对象的方法进行调用。n个引用变量指向同一个对象,通过一个变量修改对象内部数据,另一个变量看到的是修改之后的数据。2个引用变量指向同一个对象,让其中一个引用变量指向另一个对象,另一引用变量依然指向前一对象。所有函数内部都有一个变量this,它的值是调用函数的当前对象。

weixin_54372875的博客 1070

初识JS/JavaScript及其数据类型

1.ECMAScript 核心js 基础语法和内置对象函数。2.DOM(Document Object Model)文档对象模型。3.BOM(Browser Object Model)浏览器对象模型。js是一门函数优先,具有原型编程的一门需要解释器解析的编程语言。

狗头苏丹的博客 367

【JavaScript】基础内容,HTML如何引用JavaScript, JS 常用的数据类型

注意数组返回是:object。

xudahai513的博客 628

javascript-js语法基础之数据类型

在学习JavaScript之前,应该先明白学习方向。ECMAScript(核心语言规范)、DOM(文档对象模型) 和 BOM(浏览器对象模型)。而这篇文章主要讲解ECMAScript(核心语言规范),即js语法基础。js的变量。

2303_76454687的博客 942
上一篇: js数组方法解析
下一篇: JSES6知识大全
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值