JS面接問題まとめ(二)
19447 ワード
1.変数の昇格
JSコードを実行すると、コードが関数に書かれていない限り、関数のコードは生産関数のコントロール環境になります.は、リフティング中に同じ関数が一つの関数を覆い、関数が変数リフティング より優先される.
2.bind、call、appyの違い は、一つ目のパラメータに加えて、callは一つのパラメータリストを受信することができ、appyは一つのパラメータ配列 だけを受け入れることができる.
3.どのように一つのbind関数を実現しますか?
下記の関数を実現するには、⼏個端的に考えることができます.は第一のパラメータを渡さないので、デフォルトはwindow です.は、新しいオブジェクトがこの関数を実行することができるように、this指向を変更しました.考え方は新しいオブジェクトに一つの関数を追加して実行後に削除することができますか? の各関数は は、各オブジェクトに オブジェクトは、 7.相手のタイプをどう判断するかは、 です.
8.矢印関数の特徴
9.This
asyncとawaitが直接Promiseを使用する場合、thenの使用チェーンを処理して、コードをより明確で正確に書くことができるのが強みです.欠点はawaitの濫用は性能問題を引き起こす可能性があります.awaitはコードをブロックするので、その後の非同期コードは前者に依存しないかもしれませんが、前者の完成を待つ必要があります.コードの合併性が失われました.
下半身から見て、awaitを使用するコードの一つ.⿰先関数bは先に行動し、 は、 この時点で同期コードの操作が完了し、非同期コードを実行し始め、保存した値を持ち出して使用する場合、a=10です.
JSコードを実行すると、コードが関数に書かれていない限り、関数のコードは生産関数のコントロール環境になります.
b() // call b
console.log(a) // undefined
var a = 'Hello world'
function b() {
console.log('call b') }
以上のアウトプットは明らかになったと思いますが、これは関数と変数のアップグレードのためです.通常のアップグレードの解釈は声明のコードを上に移動させるということです.これは誤りがなく、大幅に理解しやすいです.しかし、より正確な説明は、生産環境においては、二つの段階があります.一つ目の段階は作成の段階で、JS解凍器は昇格させる変数と関数を探し出し、メモリの中に空間を作っておきます.関数は関数全体をメモリに貯めます.変数は声明のみでundefinedとして与えられますので、第二段階、つまりコードの保存段階で、直接に使用できます.b() // call b second
function b() {
console.log('call b first')
}
function b() {
console.log('call b second')
}
var b = 'Hello CSDN'
varは生産の多くのエラーが発生しますので、ES 6にletを導入しました.letは声明の前で使用することはできませんが、これはよく言われるletが向上しないわけではありません.letが向上し、第一段階でメモリも彼のために空間を開発しました.しかし、この声明の特性により、声明の前で使用することはできません.2.bind、call、appyの違い
call
およびapply
は、いずれも変更された指向を解決するためである.使うのは同じです.ただ、伝え方が違うだけです.let a = {
value: 1
}
function getValue(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])
bindと他の2つの構法を採用するのも同じです.ただし、この構法は一つの関数を返します.そして、私たちはビッドによって柯⽙化を実現することができます.3.どのように一つのbind関数を実現しますか?
下記の関数を実現するには、⼏個端的に考えることができます.
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
var _this = this
var args = [...arguments].slice(1)
//
return function F() {
// , new F(),
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
} }
4.どのように一つのカルル関数を実現しますか?Function.prototype.myCall = function (context) {
var context = context || window
// context
// getValue.call(a, 'yck', '24') => a.fn = getValue
context.fn = this
// context
var args = [...arguments].slice(1)
// getValue.call(a, 'yck', '24') => a.fn('yck', '24')
var result = context.fn(...args)
// fn
delete context.fn
return result
}
5.どのように一つのアプリ関数を実現しますか?Function.prototype.myApply = function (context) {
var context = context || window
context.fn = this
var result
//
// ,
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
6.プロトタイプチェーンprototype
属性を有し、Function.prototype.bind()
を除いてプロトタイプを指す.__proto__
属性があり、オブジェクトを作成する構造関数のプロトタイプを指しています.実はこの属性は[[prototype]]
を指していますが、[[prototype]]
は内部的な属性ですので、_proto_
を使ってアクセスすることはできません.__proto__
を介して当該オブジェクトに属さない属性を探し、__proto__
はオブジェクトを接続してプロトタイプチェーンを構成することができる.Object.prototype.toString.call(xx)
を通過することができる.これにより、[object Type]
のような文字列が得られます.instanceof
は、オブジェクトのタイプを正確に判断することができます.内部メカニズムは、オブジェクトのプロトタイプチェーンにタイプがあるかどうかを判断するprototype
8.矢印関数の特徴
function a() {
return () => {
return () => {
console.log(this)
}
} }
console.log(a()()())
矢印関数は実はthisがないので、この関数の中のthisは彼の外面的全面的な第一個が矢印関数の関数のthisではないことに依存します.この例⼦では、aを使用して、前頁コードの中の第一の状況に合致するため、thisはwindowである.そして、this旦は上下⽂を結んでいます.コードの変更はありません.9.This
function foo() {
console.log(this.a) }
var a = 1
foo()
var obj = {
a: 2,
foo: foo
}
obj.foo()
// `this` ,
// ,`this` `c` , `this`
var c = new foo() c.a = 3
console.log(c.a)
// call,apply,bind this, new
10.async、awaitの長所と短所asyncとawaitが直接Promiseを使用する場合、thenの使用チェーンを処理して、コードをより明確で正確に書くことができるのが強みです.欠点はawaitの濫用は性能問題を引き起こす可能性があります.awaitはコードをブロックするので、その後の非同期コードは前者に依存しないかもしれませんが、前者の完成を待つ必要があります.コードの合併性が失われました.
下半身から見て、awaitを使用するコードの一つ.
var a = 0
var b = async () => {
a = a + await 10
console.log('2', a) // -> '2' 10
a = (await 10) + a
console.log('3', a) // -> '3' 20
}b() a++
console.log('1', a) // -> '1' 1
await 10
に到達する前に変数aはまだ0であったが、await
内部でgenerators
が実現され、generators
はスタック中東⻄を保持するので、この時a=0は保存された.await
が非同期動作であるため、await
に遭遇すると、146がpending
の状態のPromise
オブジェクトに戻り、一時的に執行コードの制御権に戻り、関数外のコードが継続的に実行されるようになるので、先に処理される.