复习-js篇

1.宿主对象和原生对象的区别

"宿主对象"和"原生对象"这两个概念主要涉及到 JavaScript 运行环境中的对象。

  1. 原生对象(Native Objects):

    • 原生对象是指由 ECMAScript 规范定义的对象,它们是 JavaScript 语言本身提供的对象。例如,Array、Object、Function、String、Number、Boolean 等都是原生对象。
    • 这些对象是 JavaScript 语言的核心组成部分,其行为和特性由 ECMAScript 规范定义。
  2. 宿主对象(Host Objects):

    • 宿主对象是指由宿主环境(比如浏览器、Node.js 等)提供的对象。这些对象不属于 ECMAScript 规范,而是由具体的 JavaScript 运行环境提供的。
    • 在浏览器环境中,宿主对象包括 windowdocumentXMLHttpRequest 等。在 Node.js 环境中,宿主对象包括 globalprocessBuffer 等。
    • 宿主对象的行为和特性不受 ECMAScript 规范的约束,而是由具体的宿主环境定义。

2. Attribute 和 Property 的区别

Attribute是在HTML中定义的,而property是在DOM上定义的。

为了说明区别,假设我们在HTML中有一个文本框:

const input = document.querySelector('input');

console.log(input.getAttribute('value')); // Hello

console.log(input.value); // Hello

但是在文本框中键入“ World!”后:

console.log(input.getAttribute('value')); // Hello

console.log(input.value); // Hello World!

3.什么是'user strict',使用它有什么优缺点?

'use strict' 是用于对整个脚本或单个函数启用严格模式的语句。严格模式是可选择的一个限制 JavaScript 的变体一种方式 。
优点:

  • 无法再意外创建全局变量。
  • 会使引起静默失败(silently fail,即:不报错也没有任何效果)的赋值操抛出异常。
  • 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果)。
  • 要求函数的参数名唯一。
  • 全局作用域下,this的值为undefined。
  • 捕获了一些常见的编码错误,并抛出异常。
  • 禁用令人困惑或欠佳的功能。

缺点:

  • 缺失许多开发人员已经习惯的功能。
  • 无法访问function.caller和function.arguments。
  • 以不同严格模式编写的脚本合并后可能导致问题。

4. call,apply和bind的作用是什么?三者区别是什么?

callapplybind 是 JavaScript 中用于改变函数执行上下文的方法。它们的作用都是为了在调用函数时明确指定函数内部的 this 值,并且可以传递参数。

  1. call 方法:

    • call 方法用于调用函数,并将一个指定的 this 值和若干个参数传递给函数。
    • 语法:function.call(thisArg, arg1, arg2, ...)
  2. apply 方法:

    • apply 方法也用于调用函数,但是它接受一个包含参数的数组作为函数执行时的参数。
    • 语法:function.apply(thisArg, [arg1, arg2, ...])
  3. bind 方法:

    • bind 方法用于创建一个新函数,新函数的 this 值由 bind 的第一个参数指定,其余参数作为新函数的参数。
    • bind 方法不会立即执行函数,而是返回一个绑定了指定 this 值的新函数。
    • 语法:function.bind(thisArg[, arg1[, arg2[, ...]]])

区别:

  • callapply 的区别: 主要在于参数的传递方式,call 是一个一个传递,而 apply 是通过数组传递。
  • bind 的区别: bind 方法创建了一个新函数,并预先设置了函数的 this 值和一部分参数,但不会立即执行。它返回一个新函数,需要调用该新函数才会执行原函数。

示例:

// 示例函数
function greeting(message) {
  console.log(message, this.name);
}

var person = {
  name: 'John'
};

// 使用 call
greeting.call(person, 'Hello'); // 输出: Hello John

// 使用 apply
greeting.apply(person, ['Hi']); // 输出: Hi John

// 使用 bind
var boundGreeting = greeting.bind(person, 'Hola');
boundGreeting(); // 输出: Hola John



5.如何判断是否为空数组

var arr = [];
if (Array.isArray(arr) && arr.length === 0) {
    console.log('是空数组');
}
// Array.isArray是ES5提供的,如果不支持。用下面的方案。
if (!Array.isArray) {
    Array.isArray = function(arg) {
        return Object.prototype.toString.call(arg) === '[object Array]';
    };
}

 6.数组方法

  • map: 遍历数组,返回回调返回值组成的新数组
  • forEach: 无法break,可以用try/catch中throw new Error来停止
  • filter: 过滤
  • some: 有一项返回true,则整体为true
  • every: 有一项返回false,则整体为false
  • join: 通过指定连接符生成字符串
  • sort(fn) / reverse: 排序与反转,改变原数组
  • concat: 连接数组,不影响原数组, 浅拷贝
  • slice(start, end): 返回截断后的新数组,不改变原数组
  • splice(start, number, value...): 返回删除元素组成的数组,value 为插入项,改变原数组
  • indexOf / lastIndexOf(value, fromIndex): 查找数组项,返回对应的下标
  • reduce / reduceRight(fn(prev, cur), defaultPrev): 两两执行,prev 为上次化简函数的return值,cur 为当前值(从第二项开始)
数组乱序:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.sort(function () {
    return Math.random() - 0.5;
});


数组拆解:
// flat: [1,[2,3]] --> [1, 2, 3]

Array.prototype.flat = function() {
    return this.toString().split(',').map(item => +item )
}


push、pop、shift、unshift功能及返回值
push:添加新元素到数组末尾,返回数组长度
pop:移除数组最后一个元素,返回元素本身
unshift:添加新元素到数组开头,返回数组长度
shift:移除数组首个元素,返回元素本身
以上4种操作均会改变数组本身 

7..forEach和.map()循环的主要区别,使用场景举例

map用法:

let array = [1, 2, 3, 4, 5];
let newArray = array.map((item, i, arr) => {
    return item * 2;
});
console.log("array:", array);       // [1, 2, 3, 4, 5]
console.log("newArray:", newArray); // [2, 4, 6, 8, 10]
// 此处的array接受map方法运算之后的返回值
// 但是map方法并不能改变原来的数组



forEach用法:
let array = [1, 2, 3, 4, 5];
let newArray = array.forEach((item, i, arr) => {
    console.log('item:' + item + ', index:' + i);
    // array[i] = item * 2;    // 可以用这种方式改变原始数组的值
});
console.log("array:", array);       // [1, 2, 3, 4, 5]
console.log("newArray:", newArray); // undefined
// forEach方法没有返回值



能用forEach()做到的,map()同样可以。反过来也是如此。
map()会分配内存空间存储新数组并返回,forEach()不会返回数据。
forEach()允许callback更改原始数组的元素。map()返回新的数组。

8.如何将arguments转为数组

使用展开运算符(Spread Operator):

function getArgumentsArray() {
  var argsArray = [...arguments];
  return argsArray;
}

var result = getArgumentsArray(1, 2, 3);
console.log(result); // 输出: [1, 2, 3]

使用 Array.prototype.slice 方法: 

function getArgumentsArray() {
  var argsArray = Array.prototype.slice.call(arguments);
  return argsArray;
}

var result = getArgumentsArray(1, 2, 3);
console.log(result); // 输出: [1, 2, 3]

9.对象的遍历方法

for循环
  for (let property in obj) {
      console.log(property);
  }
但是,这还会遍历到它的继承属性,在使用之前,你需要加入obj.hasOwnProperty(property)检查。


Object.keys()
Object.keys(obj).forEach((property) => { ... })
Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组。


Object.getOwnPropertyNames()
Object.getOwnPropertyNames(obj).forEach((property) => { ... })
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。


10.数组的遍历方法

for loops
for (let i = 0; i < arr.length; i++) { ... }

forEach
 arr.forEach((item, index, arr) { ... })

map
arr.map((item, index, arr) => { ... })

11.数据类型判断方式有几种

1)typeof: 适合基本的数据类型和函数
  console.log(typeof bool);   // boolean
  console.log(typeof num);    // number
  console.log(typeof str);    // string
  console.log(typeof und);    // undefined
  console.log(typeof nul);    // object
  console.log(typeof arr);    // object
  console.log(typeof obj);    // object
  console.log(typeof fun);    // function

2)instanceof: 判断对象类型,基于原型链去判断。
obj instanceof Object: 左操作数是一个对象,右操作数是一个函数构造器或者函数对象,判断左边的操作数的原型链_proto_属性是否有右边这个函数对象的proptotype属性。

  console.log(bool instanceof Boolean);// false
  console.log(num instanceof Number); // false
  console.log(str instanceof String); // false
  console.log(und instanceof Object); // false
  console.log(arr instanceof Array);  // true
  console.log(nul instanceof Object); // false
  console.log(obj instanceof Object); // true
  console.log(fun instanceof Function);// true

  var bool2 = new Boolean()
  console.log(bool2 instanceof Boolean);// true

  var num2 = new Number()
  console.log(num2 instanceof Number);// true

  var str2 = new String()
  console.log(str2 instanceof String);//  true

  function Animation(){}
  var ani = new Animation()
  console.log(ani instanceof Animation);// true

  function Dog(){}
  Dog.prototype = new Animation()
  var dog = new Dog()
  console.log(dog instanceof Dog);    // true
  console.log(dog instanceof Animation);// true
  console.log(dog instanceof Object); // true
从结果中看出instanceof不能区别 undefined 和 null,而且对于基本类型如果不是用new声明的则也测试不出来,对于是使用new声明的类型,它还可以检测出多层继承关系。

3)constructor: 返回对创建此对象的函数的引用

  console.log(bool.constructor === Boolean);  // true
  console.log(num.constructor === Number);    // true
  console.log(str.constructor === String);    // true
  console.log(arr.constructor === Array);     // true
  console.log(obj.constructor === Object);    // true
  console.log(fun.constructor === Function);  // true

  console.log(ani.constructor === Animation); // true
  console.log(dog.constructor === Dog);       // false
  console.log(dog.constructor ===  Animation);// true

null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失。所以dog.constructor === Animation 而不是 Dog

4)Object.prototype.toString.call

  console.log(Object.prototype.toString.call(bool));  //[object Boolean]
  console.log(Object.prototype.toString.call(num));   //[object Number]
  console.log(Object.prototype.toString.call(str));   //[object String]
  console.log(Object.prototype.toString.call(und));   //[object Undefined]
  console.log(Object.prototype.toString.call(nul));   //[object Null]
  console.log(Object.prototype.toString.call(arr));   //[object Array]
  console.log(Object.prototype.toString.call(obj));   //[object Object]
  console.log(Object.prototype.toString.call(fun));   //[object Function]

  console.log(Object.prototype.toString.call(dog));   //[object Object]  


 

 原文见下面链接

「2023」前端面试知识点复盘——JS篇 - 掘金

你可能感兴趣的:(javascript,笔记,前端)