常见判断输出的题
侧边栏壁纸
  • 累计撰写 29 篇文章
  • 累计收到 1 条评论

常见判断输出的题

admin
2022-08-19 / 0 评论 / 45 阅读 / 正在检测是否收录...

一、数据类型、常见的数组方法以及异或等的判断
基本对象没有原型
数字和字符串相加,会把数字变成字符串后相加
js中为false的包括:undefined、null、false、0、NaN、""
空对象和空数组为true,new Number(x) 和New Boolean(x) 也是true
Object 和 null 双等判断是true,三等是false
null == undefined null !== undefined
null转成数字是0,Undefined 类型的值转换为 NaN
String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。
Symbol 类型的值不能转换为数字,会报错。
|| 符号:返回第一个为真的值,所有值都为假返回最后一个
&& 符号:返回第一个为假的值,所有值都为真返回最后一个
使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 是相等的
return 后的返回值如果换行了,那么会默认补齐分号,就返回undefined了,不会执行后面的了
...args必须放到最后一个参数,否则会报SyntaxError
常规函数有prototype属性,箭头函数没有
构造函数中遇到return 会直接返回return的内容
set是类数组,是对象格式
加法的时候只要有一个是字符串就会把另外一个变成字符串,其他运算符是有数字就变成数字

[..."Lydia"] === ["L", "y", "d", "i", "a"]

map():遍历数组,三个参数分别是当前值、索引、源数组。可以方便返回数组中对象的某个属性。
reduce():遍历数组,参数分别是累加器、计算的初始值、当前索引、源数组。他是会把每次执行的结果返回到累加器之中。累加器可以是一个函数,用于返回结果。如果不给第二个参数,默认把数组中的第一个元素当作累加器。

[[0, 1], [2, 3]].reduce(
 (acc, cur) => {
  return acc.concat(cur);
 },
 [1, 2]
);
 结果:[1, 2, 0, 1, 2, 3]

catch是会开辟一个新的作用域,在当前作用域内对变量进行操作,离开当前作用域就会失效。

(() => {
 let x, y;
 try {
  throw new Error();
 } catch (x) {
  (x = 1), (y = 2);
  console.log(x);
 }
 console.log(x);
 console.log(y);
})();
结果:1 undefined 2
function sayHi() {
 return (() => 0)();
}

typeof sayHi() === 'number'  因为是立即执行函数
// 对象键会自动转换为字符串,且对象自动转换的字符串会变成[Object object]
// 所以a[b] == a["Object object"]  a[c] == ["Object object"]
// 这个时候就把值给覆盖了
const a = {};
const b = { key: "b" };
const c = { key: "c" };

a[b] = 123;
a[c] = 456;

console.log(a[b]);
// 如果不是用new调用构造函数,那么this的指向是window,传值的话也是传到了window身上
// 所以sarah是undefined
function Person(firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

const lydia = new Person('Lydia', 'Hallie')
const sarah = Person('Sarah', 'Smith')

console.log(lydia)
console.log(sarah)
// 不能直接给构造函数添加方法,要在原型上添加。
// 原因是如果在原型身上添加的方法不一定每个对象都用得到,且这种添加方法会使得每个实例都增加这个方法,占用内存,所以规定要在原型上添加.
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

const member = new Person("Lydia", "Hallie");
Person.getFullName = function () {
  return `${this.firstName} ${this.lastName}`;
}

console.log(member.getFullName());
结果:TypeError
// 如果使用标记模板字面量,第一个参数的值总是包含字符串的数组。其余的参数获取的是传递的表达式的值!
function getPersonInfo(one, two, three) {
  console.log(one)
  console.log(two)
  console.log(three)
}

const person = 'Lydia'
const age = 21

getPersonInfo`${person} is ${age} years old`
function getAge() {
  'use strict'
  age = 21
  console.log(age)
}

getAge()

结果:ReferenceError
// [x, ...y] = [1, 2, 3, 4]     [1, [2, 3, 4]]
// 对于箭头函数,如果只返回一个值,我们不必编写花括号。但是,如果您想从一个箭头函数返回一个对象,您必须在圆括号之间编写它,否则不会返回任何值
const getList = ([x, ...y]) => [x, y]
const getUser = user => { name: user.name, age: user.age }

const list = [1, 2, 3, 4]
const user = { name: "Lydia", age: 21 }

console.log(getList(list))
console.log(getUser(user))
// Symbol类型是不可枚举的。Object.keys方法返回对象上的所有可枚举的键属性。Symbol类型是不可见的,并返回一个空数组。 记录整个对象时,所有属性都是可见的,甚至是不可枚举的属性。
const info = {
  [Symbol('a')]: 'b'
}

console.log(info)
console.log(Object.keys(info))
// Object.entries是获取可以枚举的键值对属性,返回的是数组
// for of 循环可以迭代数组中的每个元素
// [x,y] 是解构了for of下的子数组,x
const person = {
  name: "Lydia",
  age: 21
}

for (const [x, y] of Object.entries(person)) {
  console.log(x, y)
}
// 参数内的运算会判断另外一个参数是否已经有值
function sum(num1, num2 = num1) {
  console.log(num1 + num2)
}

sum(10)
结果:20

function test(m = n, n = 2) {
 console.log(m, n)
}
test() // Uncaught ReferenceError: Cannot access 'n' before initialization
test(3) // 3 2
test(3, 4) // 3 4
// 使用import * as name语法,我们将module.js文件中所有export导入到index.js文件中,并且创建了一个名为data的新对象。 在module.js文件中,有两个导出:默认导出和命名导出。 默认导出是一个返回字符串“Hello World”的函数,命名导出是一个名为name的变量,其值为字符串“Lydia”。
// data对象具有默认导出的default属性,其他属性具有指定exports的名称及其对应的值。
// module.js 
export default () => "Hello world"
export const name = "Lydia"

// index.js 
import * as data from "./module"

console.log(data)
结果 { default: function default(), name: "Lydia" }
console.log(typeof typeof 1)
结果:string
// 返回一个唯一的id
// setInterval 返回一个唯一的 id。此 id 可被用于 clearInterval 函数来取消定时。
setInterval(() => console.log('Hi'), 1000)
// 一般的函数在执行之后是不能中途停下的。但是,生成器函数却可以中途“停下”,之后可以再从停下的地方继续。当生成器遇到yield关键字的时候,会生成yield后面的值。注意,生成器在这种情况下不 返回 (return )值,而是 生成 (yield)值。
// 首先,我们用10作为参数i来初始化生成器函数。然后使用next()方法一步步执行生成器。第一次执行生成器的时候,i的值为10,遇到第一个yield关键字,它要生成i的值。此时,生成器“暂停”,生成了10。
// 然后,我们再执行next()方法。生成器会从刚才暂停的地方继续,这个时候i还是10。于是我们走到了第二个yield关键字处,这时候需要生成的值是i*2,i为10,那么此时生成的值便是20。所以这道题的最终结果是10,20。
function* generator(i) {
  yield i;
  yield i * 2;
}

const gen = generator(10);

console.log(gen.next().value);  10
console.log(gen.next().value);   20
// 当我们向Promise.race方法中传入多个Promise时,会进行 优先 解析。在这个例子中,我们用setTimeout给firstPromise和secondPromise分别设定了500ms和100ms的定时器。这意味着secondPromise会首先解析出字符串two。那么此时res参数即为two,是为输出结果。
const firstPromise = new Promise((res, rej) => {
  setTimeout(res, 500, "one");
});

const secondPromise = new Promise((res, rej) => {
  setTimeout(res, 100, "two");
});

Promise.race([firstPromise, secondPromise]).then(res => console.log(res));
结果 two
// for in 迭代的是key
const person = {
  name: "Lydia",
  age: 21
};

for (const item in person) {
  console.log(item);
}
// parseInt遇到不是数字的字符就直接返回,忽略后面的
const num = parseInt("7*6", 10);
结果:7
// map会返回一个新数组
[1, 2, 3].map(num => {
  if (typeof num === "number") return;
  return num * 2;
});
// 值传递和引用传递
function getInfo(member, year) {
  member.name = "Lydia";
  year = "1998";
}

const person = { name: "Sarah" };
const birthYear = "1997";

getInfo(person, birthYear);

console.log(person, birthYear);
// 结果  { name: "Lydia" }, "1997"
// 引入的模块是 只读 的: 你不能修改引入的模块。只有导出他们的模块才能修改其值。
// 当我们给myCounter增加一个值的时候会抛出一个异常: myCounter是只读的,不能被修改。
// counter.js
let counter = 10;
export default counter;
// index.js
import myCounter from "./counter";

myCounter += 1;

console.log(myCounter);
结果:Error
// 但是通过 var, const 或 let 关键字声明的变量无法用 delete 操作符来删除。delete一般用于删除对象中的属性
const name = "Lydia";
age = 21;

console.log(delete name); false
console.log(delete age); true
// 相当于解构赋值,但是参数不够,就只赋值有的参数
const numbers = [1, 2, 3, 4, 5];
const [y] = numbers;

console.log(y);  1
// 扩展运算符...为对象的组合提供了可能。你可以复制对象中的键值对,然后把它们加到另一个对象里去。在本例中,我们复制了user对象键值对,然后把它们加入到admin对象中
const user = { name: "Lydia", age: 21 };
const admin = { admin: true, ...user };

console.log(admin);
结果:{ admin: true, name: "Lydia", age: 21 }

二、this指向相关问题
属性中的this指向window!属性中的方法指向调用者
对象中的属性如果是一个函数,那么这个函数指向调用者。如果对象中有一个要执行的函数,那么这个函数指向window
JavaScript自执行函数this指向window
函数中的函数中的this指向window

// 首先从fn2函数调用开始,这里有个实参obj.getA,指的是obj对象里getA方法,而getA方法是fn1,即相当于在fn2里传了fn1函数,由于作用域,a输出6,this这里指的是window对象,故this.a值为5。
var a = 5;
function fn1() {
    var a = 6;
    console.log(a);
    console.log(this.a);
}
function fn2(fn) {
    var a = 7;
    fn();
}
var obj = {
    a: 8,
    getA: fn1
}
fn2(obj.getA);
结果: 6  5 
// 这道题有点意思:首先我们分析我们把5这个实参传给了test函数的形参,函数体内this指向window,即在window下添加了一个x属性值为5,函数返回这个window对象通过全局变量x接受,但由于此时x也是window对象上的,执行x.x时它会覆盖之前window.x=5,现在是window.x=window,所以它不会向我们想的那样拿到5,而是无限循环访问window对象;而执行y = test(6)时,把6传进去,此时window对象上的x又一次被覆盖,现在是window.x=6,通过全局变量y去接受这个返回值window对象,相当于是window.y=window,即此时window.x=6了,y变为window对象了,可以通过y.x访问到6,用x.x访问时全局变量x变成了数值了,故是undefined。
function test(arg) {
    this.x = arg;
    return this;
}
var x = test(5);
var y = test(6);
console.log(x.x);
console.log(y.x);

x.x => undefined
y.x => 6

三、宏任务微任务

    let promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('once')
            resolve('success')
        }, 1000);
    })
    promise.then((res) => {
        console.log(res, 1)
    })
    promise.then((res) => {
        console.log(res, 2)
    })
结果:once success 1  success 2
0

评论 (0)

取消