JavasScript基础第一部分

此文章,来源于印客学院的资料,然后补充的。

此文档不一定涵盖了所有知识点,只是一个大概方向,仅供参考。

也算一个查漏补缺,诸君可以根据自己实际情况,自行衡量,看看哪里需要补充。

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

JavaScript 共有八种数据类型,分别是 UndefinedNullBooleanNumberStringObjectSymbolBigInt

其中 SymbolBigIntES6 中新增的数据类型:

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

这些数据可以分为 原始数据类型引用数据类型

  • :原始数据类型(Undefined、Null、Boolean、Number、String)
  • :引用数据类型(对象、数组和函数)

两种类型的区别在于存储位置的不同:

  • 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
  • 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。

如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

堆和栈的概念存在于数据结构操作系统内存中,在数据结构中:

  • 在数据结构中,栈中数据的存取方式为先进后出。
  • 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。

在操作系统中,内存被分为栈区和堆区:

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

更多精彩内容,请微信搜索“前端爱好者戳我 查看

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

在JavaScript中,有多种方式可以进行数据类型检测。以下是一些常见的方式:

使用typeof操作符:typeof是JavaScript的一元操作符,可以返回一个值的数据类型。

例如:

console.log(typeof "Hello World");  // 输出 "string"
console.log(typeof 42);  // 输出 "number"
console.log(typeof true);  // 输出 "boolean"

使用instanceof操作符:instanceof用于检查一个对象是否属于某个特定的类或构造函数的实例。

例如:

var arr = [];
console.log(arr instanceof Array);  // 输出 true

var date = new Date();
console.log(date instanceof Date);  // 输出 true

使用constructor属性:可以使用constructor属性来判断一个对象的构造函数。

例如:

var str = "Hello World";
console.log(str.constructor === String);  // 输出 true

var num = 42;
console.log(num.constructor === Number);  // 输出 true

使用Object.prototype.toString()方法:可以使用该方法来获取一个对象的内部属性[[Class]],从而判断其数据类型。

例如:

var obj = {};
console.log(Object.prototype.toString.call(obj));  // 输出 "[object Object]"

var func = function() {};
console.log(Object.prototype.toString.call(func));  // 输出 "[object Function]"

这些只是一些基本的方式,还有其他更复杂和详细的方式,如使用typeof和constructor结合判断、使用Array.isArray()方法判断数组等。

根据实际需求选择适合的方式进行数据类型检测。

null 和undefined 区别

在JavaScript中,null和undefined是两个特殊的值,用于表示缺失或无效的值。

null是一个表示空值的特殊关键字。它被认为是一个空对象指针,表示该变量没有指向任何有效的对象。当我们想要明确指示一个变量为空时,可以将其赋值为null。例如:

let myVariable = null;
console.log(myVariable);  // 输出:null

undefined表示一个未定义的值,表示变量已经声明但尚未被赋值。当我们声明一个变量但没有给它赋初始值时,该变量的默认值为undefined。另外,如果我们访问一个不存在的属性或者调用一个不存在的函数,返回值也为undefined。例如:

let myVariable;
console.log(myVariable);  // 输出:undefined

此外,null和undefined在使用方式上也有区别。当你希望表达一个变量有值但目前为空时,可以使用null。而undefined则通常表示未定义、缺失或错误的状态。

总结一下:

  • null表示为空的值,是一个空对象指针。
  • undefined表示未定义的值,表示变量已声明但未赋值,或者访问不存在的属性或函数时的返回值。

需要注意的是,在使用时要避免混淆null和undefined,根据具体情况正确选择使用。

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

在 JavaScript 中,instanceof 是一个运算符,用于 检查对象是否属于指定类或其原型链上的某个类。它的实现原理可以描述如下:

  1. instanceof 首先会判断左操作数(对象)是否有 [[Prototype]] 属性,该属性指向对象的原型。
  2. 接下来,它会判断右操作数(构造函数)是否具有 prototype 属性,该属性指向构造函数的原型对象。
  3. 如果左操作数的 [[Prototype]] 属性为 null,则返回 false。如果右操作数的 prototype 属性为 null,则抛出 TypeError 异常。
  4. 然后,instanceof 将沿着左操作数的原型链逐级查找,直到找到右操作数的 prototype,或者到达原型链的尽头(null)为止。
  5. 如果找到了匹配的原型对象,则返回 true;否则返回 false

这个过程是通过比较原型链中的对象是否与右操作数的 prototype 相等来完成的。

以下是一个简单的示例代码,演示如何使用 instanceof 运算符:

class Animal { }

class Dog extends Animal { }

const animal = new Dog();

if (animal instanceof Dog) {
  console.log('animal 是 Dog 类型');
} else if (animal instanceof Animal) {
  console.log('animal 是 Animal 类型');
} else {
  console.log('animal 不是 Dog 类型也不是 Animal 类型');
}

在上述示例中,instanceof 运算符首先判断 animal 是否是 Dog 类的一个实例。由于 animal 是通过 new Dog() 创建的,所以它是 Dog 类的实例,输出 “animal 是 Dog 类型”。

如何获取安全的 undefined 值?

因为 undefined 是一个标识符,所以可以被当作变量来使用和赋值,但是这样会影响 undefined 的正常判断。

表达式 void 没有返回值,因此返回结果是 undefined。void 并不改变表达式的结果,只是让表达式不返回值。

因此可以用 void 0 来获得 undefined。

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

在JavaScript中,Object.is() 方法和比较操作符 “=" 和 "” 在比较值时有一些区别。

  1. Strict Equality (严格相等,“===”):
    • 使用 “===” 进行比较时,会先判断两个值的数据类型是否相同,如果不同则直接返回 false。
    • 如果两个值的数据类型相同,再进一步比较它们的值。
    • 使用 “===” 比较时,对于数字、字符串、布尔值等基本类型的值,只有在值相同的情况下才会返回 true。
    • 对于引用类型的值(如对象、数组等),比较的是它们在内存中的引用地址,只有当两个引用指向同一个对象时才会返回 true。

示例:

console.log(42 === 42);  // 输出 true
console.log("hello" === "hello");  // 输出 true
console.log(true === true);  // 输出 true

var obj1 = {};
var obj2 = obj1;
console.log(obj1 === obj2);  // 输出 true
  1. Abstract Equality (抽象相等,“==”):
    • 使用 “==” 进行比较时,会进行类型转换,尝试将两个值转换为相同的类型,然后再进行比较。
    • 在进行类型转换时,会根据一些规则进行隐式类型转换,例如将字符串转换为数字。
    • 如果两个值的类型相同,则和使用 “===” 比较相同。
    • 如果两个值的类型不同,会尝试将它们转换为相同的类型进行比较。具体转换规则相对复杂,不太直观。

示例:

console.log(42 == "42");  // 输出 true,进行了类型转换后相等
console.log(null == undefined);  // 输出 true,特殊规则,被认为相等

var obj = {};
console.log(obj == "[object Object]");  // 输出 true,对象和字符串进行了隐式类型转换
  1. Object.is() 方法:
    • Object.is() 方法用于比较两个值是否严格相等,类似于 “===” 操作符。
    • 与 “===” 不同的是,Object.is() 方法对于一些特殊情况的处理更加准确。
    • 特殊情况包括处理 NaN 和处理 +0/-0 的区别。

示例:

console.log(Object.is(NaN, NaN));  // 输出 true,对于 NaN 的判断更准确
console.log(Object.is(+0, -0));    // 输出 false,对于 +0/-0 的判断更准确

综上所述,Object.is() 方法在比较值时更准确,特别是对于 NaN 和 +0/-0 的处理。在一般情况下,推荐使用 “===” 进行严格相等比较。

什么是 JavaScript 中的包装类型?

JavaScript中的包装类型(Wrapper Types)是指用于将原始数据类型(Primitive Data Type)包装成对象的特殊对象。

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

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

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

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

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

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

JavasScript基础第一部分_第1张图片

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

你可能感兴趣的:(前端杂货铺,javascript,ecmascript)