フロントエンドのインタビューJsの記事

1. 请解释事件代理(event delegation)

多くの要素にイベントを追加する必要がある場合は、親ノードにイベントを追加してイベントを委任してハンドラをトリガできます。 ブラウザのイベントバブリングメカニズムを利用します。

var delegate = function(client, clientMethod) {
  return function() {
      return clientMethod.apply(client, arguments);
  }
}

var agentMethod = delegate (client, clientMethod);
agentMethod();


// 获取父节点,并为它添加一个click事件
document.getElementById("parent-list").addEventListener("click",function(e) {
  // 检查事件源e.targe是否为Li
  if(e.target && e.target.nodeName.toUpperCase == "LI") {
    // 真正的处理过程在这里
    console.log("List item ",e.target.id.replace("post-")," was clicked!");
  }
});


2. 谈谈浏览器的事件冒泡机制

ブラウザのベンダーによって、イベントキャプチャと処理の処理メカニズムが異なります。例としてDOM2.0で定義されたW3C標準イベントを考えてみましょう。
DOM2.0モデルは、イベント処理フローを3つのフェーズ(1つはイベント取得フェーズ、2番目はイベントターゲットフェーズ、3番目はイベントバブルフェーズ)に分割されます。

  • イベントキャプチャ:イベントが実際に発生したターゲット要素に到達するまで、DOMツリーのノードがターゲット要素ノードに流れるので、要素がイベント(onclickなど)をトリガすると、トップレベルのオブジェクトドキュメントがイベントストリームを放出します。 このプロセスでは、イベントの対応するリスナー機能はトリガーされません。

  • イベントターゲット:ターゲットエレメントに到達した後、イベントのターゲットエレメントの対応する処理機能を実行します。 リスナー関数がバインドされていない場合、リスナー関数は実行されません。

  • イベントのバブリング:ターゲット要素から開始し、最上位要素に伝播します。 途中でノードが対応するイベントハンドラにバインドされている場合、これらの関数は1回トリガされます。 イベントのバブリングを防止したい場合は、e.stopPropagation()(Firefox)またはe.cancelBubble = true(IE)を使用してイベントのバブリング伝播を整理できます。


JavaScript 中this 是如何工作的。ますJavaScript 中this 是如何工作的。

  • 関数呼び出しとして、これはグローバルオブジェクトをバインドし、ブラウザ環境グローバルオブジェクトはウィンドウです。

  • 内部関数はこれもグローバルオブジェクトをバインドし、その外部関数に対応するオブジェクトにバインドする必要があります。これはJavaScriptのバグです。

  • コンストラクタとして使用され、これは新しく作成されたオブジェクトにバインドされます。

  • オブジェクトメソッドとして使用され、これはオブジェクトにバインドされます。

  • applyまたはcallでこれを呼び出すと、関数呼び出しの最初の引数に明示的に設定されます。


4. 谈谈CommonJs 、AMD 和CMD

CommonJS仕様では、別のファイルがモジュールです。 各モジュールはCommonJSの使用のための別のスコープです:NodeJS

AMDは非同期モジュール定義非同期モジュール定義です。ブラウザ側でモジュール式に開発された仕様で、AMDは、昇格プロセスでRequireJSによってモジュールの定義が標準化された出力です。

CMD(Common Module Definition)は、その表現をSeaJSとして定義します。

requireJSは主に2つの問題を解決します

  • 複数のjsファイルに依存関係がある可能性があり、依存するファイルを依存するファイルより前に依存するファイルをブラウザーにロードする必要があります。

  • jsがロードされると、ブラウザはページのレンダリングを停止します。ファイルが多くロードされるほど、ページのレスポンス時間は長くなります。

CMDとAMDの違い

  • AMDは、前置詞に頼って、モジュールを定義する際に依存するモジュールを宣言します。

  • CMDは最も近い依存関係を尊重します。モジュールを使用してから、


5. 谈谈对IIFE的理解

IIFE即座に呼び出される関数式すぐに関数式を実行する

お勧めしません

(function(){})();

おすすめ

(function(){}());

パーサがコードを解釈するときには、最初にencounters()が呼び出され、functionキーワードが見つかると、()内のコードが関数宣言ではなく関数式として自動的に認識されます。 。

知識開発:

function(){ /* code */ }();  解释下该代码能正确执行吗?

いいえ、javascriptコードが解釈されたときに、functionキーワードを検出すると、関数式ではなく、デフォルトで関数宣言として扱われます。明示的に関数式として表現されていない場合、関数宣言には関数名が必要です。また、上のコードの関数には関数名がありません。 (上記のコードは最初の左かっこにも実行されます(報告されている場合、理論上は関数名が必要です)。

function foo(){ /* code */ }();  解释下该代码能正确执行吗?

式の後に括弧を追加すると、式がすぐに実行され、括弧が続く場合は括弧が前のステートメントと一致せず、操作を制御するグループ化演算子になります。優先順位(括弧内の最初の演算)は、最初にfooという関数を宣言し、()の式演算を実行するのと同じですが、()(グループ演算子)の式を空にすることはできません。 (上記のコードは、右括弧を実行すると、式が空であることが分かり、エラーが報告されます)。


6. .call 和.apply 的区别是什么?

    foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments)==this.foo(arg1, arg2, arg3)

呼び出しメソッドと適用メソッドの違いは、2番目のパラメーターから呼び出されたメソッドのパラメーターが、借用されたメソッドにパラメーターとして渡され、直接適用されて配列に渡され、次に渡されるということです。 。


7. 请解释Function.prototype.bind?

bind()メソッドは、bodyオブジェクト内の値がbind()関数に渡される値にバインドされた関数を作成します。

原則

Function.prototype.bind = function(context) {
 var self = this; // 保存原函数
 return function() { // 返回一个新函数
  return self.apply(context, arguments); // 执行新函数时,将传入的上下文context作为新函数的this
 }
}

使用法:

var paint = {
 color: "red",
 count: 0,
 updateCount: function() {
  this.count++;
  console.log(this.count);
 }
};

// 事件处理函数绑定的错误方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount); // paint.updateCount函数的this指向变成了该DOM对象

// 事件处理函数绑定的正确方法:
document.querySelector('button')
 .addEventListener('click', paint.updateCount.bind(paint)); // paint.updateCount函数的this指向变成了paint


请解释原型继承(prototypal inheritance) 的原理。

オブジェクトのプロパティをルックアップすると、JavaScriptはプロトタイプチェーンを横断して、指定された名前のプロパティを見つけます。 – JavaScript Secret Gardenから

JavaScriptのすべてのオブジェクトには組み込みのprotoプロパティがあります。 このプロパティはプログラミングからは見えません(このプロパティはES6標準で開いていますが、ブラウザはこのプロパティの可視性をサポートしています)。実際には別のオブジェクトへの参照またはnullです。

オブジェクトが属性を参照する必要がある場合、JavaScriptエンジンはオブジェクトのプロパティシートから属性識別子を最初に探し、それが見つかった場合は対応する読み書き操作を実行し、独自のプロパティシートに見つからない場合はprotoプロパティで参照されます。プロパティまたはprotoプロパティがnullを指すまで、オブジェクトのプロパティシートなどを探します。

次のコードは、JSエンジンがどのようにプロパティを探すかを示しています。

//__proto__ 是一个不应在你代码中出现的非正规的用法,这里仅仅用它来解释JavaScript原型继承的工作原理。
function getProperty(obj, prop) {
if (obj.hasOwnProperty(prop))
    return obj[prop]
else if (obj.__proto__ !== null)
    return getProperty(obj.__proto__, prop)
else
    return undefined
}

JSのECMA仕様では、プロトタイプ継承にnew演算子を使用することしかできません

プロトタイプ継承

function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
    print: function () { console.log(this.x, this.y); }
};

var p = new Point(10, 20);
p.print(); // 10 20

ちなみに、新しい演算子はどのように動作しますか?

  • クラスのインスタンスを作成します 。 このステップでは、空のオブジェクトのprotoプロパティをF.prototypeに設定します。

  • インスタンスを初期化します 。 関数Fが渡されて呼び出され、キーワードthisがインスタンスに設定されます。

  • インスタンスを返します

function New (f) {
    var n = { '__proto__': f.prototype }; /*第一步*/
    return function () {
        f.apply(n, arguments);            /*第二步*/
        return n;                         /*第三步*/
    };
}

JavaScriptの真のプロトタイプ継承

Object.create = function (parent) {
    function F() {}
    F.prototype = parent;
    return new F();
};

真のプロトタイプ継承(Object.createや__proto__など)を使用しても、次のような欠点があります。

  • 基準が貧弱:__proto__は標準的な使用法でも、不承認の使用でもありません。 同時に、元のObject.createとDaoによって書かれた元のバージョンは同じではありません。

  • 不十分な最適化:ネイティブオブジェクトでもカスタムオブジェクトでも、パフォーマンスは新しいものよりはるかに最適化されていません。前者は後者よりも最大10倍遅いです。

ES6内部実装クラスとクラス継承

class Parent {
    constructor(name) { //构造函数
          this.name = name;
    }
    say() {
          console.log("Hello, " + this.name + "!");
    }
}

class Children extends Parent {
    constructor(name) { //构造函数
        super(name);    //调用父类构造函数
        // ...
    }
    say() {
          console.log("Hello, " + this.name + "! hoo~~");
    }
}

リファレンス:


9. 请尽可能详尽的解释AJAX 的工作原理

Ajaxの原則は、単にXmlHttpRequestオブジェクトを介してサーバーに非同期要求を行い、サーバーからデータを取得し、JavaScriptを使用してDOMを操作してページを更新することです。 これで最も重要なステップは、サーバーから要求データを取得することです。

ajaxの動作原理を使用しないでください

ajaxの使い方


10. javascript中"attribute" 和"property" 的区别是什么?

属性と属性は非常に混乱しており、2つの単語の中国語の翻訳は非常に似ています(属性:属性、属性:属性)が、実際には2つは異なるものであり、異なるカテゴリに属します。 すべてのDOMオブジェクトにはデフォルトの基本プロパティがあり、作成されると基本プロパティのみが作成されます.TAGタグに含まれるカスタムプロパティはDOMに直接配置されません。

  • プロパティはDOM内の属性であり、JavaScript内のオブジェクトです。

  • 属性はHTMLタグ上の属性で、その値は文字列のみになります。

  • DOMにはデフォルトの基本プロパティがあり、プロパティと呼ばれます。いずれの場合も、初期化時にDOMオブジェクトに作成されます。

  • これらの属性がTAGに割り当てられている場合、これらの値は初期値と同じ名前のDOMのプロパティに割り当てられます。


元のリンク