ホームページ > 記事 > ウェブフロントエンド > JavaScrip の面接でよくある質問と回答のまとめ
この記事は、JavaScript に関する一般的な面接の質問と回答をまとめたもので、困っている方の参考になれば幸いです。
1. これが JavaScript でどのように機能するかを説明してください。
まず第一に、これは常に、関数が作成されたオブジェクトではなく、関数が実行されているオブジェクトを指します。無名関数、またはどのオブジェクトにも存在しない関数は window を指します。
1. メソッド呼び出しモード
関数をオブジェクトの属性として保存すると、そのオブジェクトのメソッドになります。関数内の this の値はオブジェクトです。
var foo = { name: 'fooname', getName: function (){ return this.name } } foo.getName(); // this => foo
2. 関数呼び出しモード
関数がオブジェクトの属性ではない場合。関数内の this の値はグローバル オブジェクトです。
注意: メソッドの内部関数内の this の値もグローバル オブジェクトであり、外部関数の this ではありません
function foo(){ this.name = 'fooname'; } foo(); // this => window
3。 mode
つまり、new を使用して関数が呼び出された場合、これは新しく構築されたオブジェクトにバインドされます。
function Foo(){ this.name = 'fooname'; } var foo = new Foo(); // this => foo
4. apply または call 呼び出しモードを使用する
このモードで呼び出す場合、関数内の this は、apply または call メソッドの呼び出し時に受け入れられる最初のパラメーターにバインドされます。
function getName(name){ this.name = name; } var foo = {}; getName.call(foo, name); // this =>foo
this の値を変更する主なメソッド (現在考えられています。コメントの追加を歓迎します):
apply メソッドまたは call メソッドが呼び出されたときに強制的に変更して、this が最初のパラメーターを指すようにします。 。
Function.bind メソッドを使用して新しい関数を作成します。新しい関数の this は、指定された最初のパラメーターを指します。
2. プロトタイプ継承の原理を説明してください。
JavaScript には「サブクラス」と「親クラス」の概念がなく、継承の実装にはすべて「プロトタイプ チェーン」モードが必要です。
各関数 Sub には、プロトタイプ オブジェクトを指す属性があります。また、プロトタイプ オブジェクトには、new を通じてインスタンス インスタンスを生成し、このインスタンスまたはメソッドの特定の属性を持っている場合、インスタンスは最初にこのメソッドまたは属性を持っているかどうかを確認し、そうでない場合は、インスタンスのコンストラクター Sub.prototype のプロトタイプを検索します。 .prototype には、別の型のインスタンスが割り当てられます。 superInstance 内で検索されます。この superInstance には、特定のプロトタイプ オブジェクトを指す属性プロトタイプもあり、最終的に Object.prototype に到達し、プロトタイプの継承が形成されます。
この原則を使用して、継承関数を自分で実装します:
function inherits(subType, superType){ var _prototype = Object.create(superType.prototype); _prototype.constructor = subType; subType.prototype = _prototype; }
3. 次のコードが IIFE (すぐに呼び出される関数式) ではない理由を説明してください。 IIFE にするにはどのような変更を加える必要がありますか?
(function fn(){..})()
、関数は括弧で囲まれ、式の後に続きます。 () を使用すると、関数はすぐに実行されます。
IIFE の一部の機能:
スコープを作成し、多数の一時変数コードを内部に保存して、名前の競合を防ぎます。
一部のライブラリの外層は、スコープの汚染を防ぐためにこの形式でラップされています。
一度だけ実行されるコードを実行します。
4. (function fn(){..})()、関数は括弧内に含まれており、その後に () が続く式になります。この関数をすぐに実行します。 。
IIFE の一部の機能:
スコープを作成し、多数の一時変数コードを内部に保存して、名前の競合を防ぎます。
一部のライブラリの外層は、スコープの汚染を防ぐためにこの形式でラップされています。
一度だけ実行されるコードを実行します。
関数が呼び出されると、実行環境とスコープ チェーンが作成され、引数やその他の名前付きパラメーターに基づいてアクティブ オブジェクトを形成するために初期化されます。外部関数呼び出しが終了すると、その実行環境とスコープ チェーンは破棄されますが、そのアクティブ オブジェクトはクロージャに保存され、クロージャ関数呼び出しの終了後に最終的に破棄されます。簡単に言えば、クロージャは他の関数の内部変数を読み取ることができる関数です。 JavaScript では、クロージャは、別の関数のスコープ内の変数にアクセスできる関数です。
使用方法: A 関数の戻り値として、A 関数内の B 関数を返します。
理由:
1. 匿名の自己実行関数
一部のシナリオでは、関数は 1 回だけ実行する必要があります。 as init() このような内部変数を維持する必要のない関数の場合は、クロージャを使用できます。無名関数を作成し、すぐに実行しました。内部変数は外部から参照できないため、グローバル オブジェクトを汚すことなく、関数の実行後すぐにリソースが解放されます。
2. カプセル化
カプセル化のためのオブジェクト指向のコード スタイルをシミュレートし、プライベート プロパティが存在できるようにします。
5. .call と .apply の違いは何ですか?
.call と .apply の共通点は、両方とも関数本体内のこのオブジェクトの値を変更するために使用されることです。
違いは、2 番目のパラメーターが異なることです。 apply() の 2 番目のパラメーターは配列のようなオブジェクト引数であり、パラメーターはすべて配列の形式で渡されますが、call() は一連のパラメーターをそれに渡します。例:
Math.max.call(null, 1, 2, 3, 4); //4 Math.max.apply(null, [1, 2, 3, 4]); //4
6. Function.prototype.bind について説明してください。
Function.prototype.bind方法会创建一个新函数,当这个新函数被调用时,它的this值是传递给bind()的第一个参数, 它的参数是bind()的其他参数和其原本的参数.
七、请指出 JavaScript 宿主对象 (host objects) 和原生对象 (native objects) 的区别?
宿主对象是指DOM和BOM。
原生对象是Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、Math等对象。
八、请指出以下代码的区别:function Person(){}、var person = Person()、var person = new Person()?
function Person(){}
声明一个函数Person()。
var person = Person()
将函数Person()的结果返回给变量person,如果没有返回值则person为undefined。
var person = new Person()
new一个Person的实例对象。
九、请尽可能详尽的解释 Ajax 的工作原理。以及使用 Ajax 都有哪些优劣?
Ajax是无需刷新页面就能从服务器取得数据的一种方法。
Ajax通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM更新页面。
过程
创建XMLHttpRequest对象。
设置响应HTTP请求的回调函数。
创建一个HTTP请求,指定相应的请求方法、url等。
发送HTTP请求。
获取服务器端返回的数据。
使用JavaScript操作DOM更新页面。
缺点
对搜索引擎不友好
要实现Ajax下的前后退功能成本较大
跨域问题限制
十、请解释变量声明提升 (hoisting)。
变量的声明前置就是把变量的声明提升到当前作用域的最前面。
函数的声明前置就是把整个函数提升到当前作用域的最前面(位于前置的变量声明后面)。
//变量的声明前置 console.log(num);//undefined var num = 1; 等价于 //变量的声明前置 var num; console.log(num);//undefined num = 1;
十一、请描述事件冒泡机制 (event bubbling)。
事件冒泡(event bubbling),事件最开始时由触发的那个元素身上发生,然后沿着DOM树向上传播,直到document对象。如果想阻止事件起泡,可以使用e.stopPropagation()。
十二、什么是 “use strict”; ? 使用它的好处和坏处分别是什么?
优点
消除Javascript语法的一些不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的Javascript做好铺垫。
缺点
严格模式改变了语义。依赖这些改变可能会导致没有实现严格模式的浏览器中出现问题或者错误。
十三、请解释 JavaScript 的同源策略 (same-origin policy)。
同源策略限制了一个源(origin)中加载文本或脚本与来自其它源(origin)中资源的交互方式。同源指的是协议、域名、端口相同,同源策略是一种安全协议。
十四、请解释 JSONP 的工作原理,以及它为什么不是真正的 Ajax。
JSONP(JSON with Padding)是一种非官方跨域数据交互协议,它允许在服务器端集成< script >标签返回至客户端,通过javascript回调的形式实现跨域访问。
因为同源策略的原因,我们不能使用XMLHttpRequest与外部服务器进行通信,但是< script >可以访问外部资源,所以通过JSON与< script >相结合的办法,可以绕过同源策略从外部服务器直接取得可执行的JavaScript函数。
原理
客户端定义一个函数,比如jsonpCallback,然后创建< script >,src为url + ?jsonp=jsonpCallback这样的形式,之后服务器会生成一个和传递过来jsonpCallback一样名字的参数,并把需要传递的数据当做参数传入,比如jsonpCallback(json),然后返回给客户端,此时客户端就执行了这个服务器端返回的jsonpCallback(json)回调。
通俗的说,就是客户端定义一个函数然后请求,服务器端返回的javascript内容就是调用这个函数,需要的数据都当做参数传入这个函数了。
优点 - 兼容性好,简单易用,支持浏览器与服务器双向通信
缺点 - 只支持GET请求;存在脚本注入以及跨站请求伪造等安全问题
补充一点,JSONP不使用XMLHttpRequest对象加载资源,不属于真正意义上的AJAX。
十五、== 和 === 有什么不同?
通俗的说就是===比==要更为严格,===比较过程中没有任何的类型转换。
十六、什么是三元表达式 (Ternary expression)?“三元 (Ternary)” 表示什么意思?
如名字表示的三元运算符需要三个操作数。
语法是
条件 ? 结果1 : 结果2;
这里你把条件写在问号(?)的前面后面跟着用冒号(:)分隔的结果1和结果2。满足条件时结果1否则结果2。
十七、你怎么看 AMD vs. CommonJS?
浏览器端异步和服务器端同步的模块化编程规范
十八、请举出一个匿名函数的典型用例?
定义回调函数,立即执行函数,作为返回值的函数,使用方法var foo = function() {}定义的函数。
十九、描述以下变量的区别:null,undefined 或 undeclared?该如何检测它们?
未定义的属性、定义未赋值的为undefined,JavaScript访问不会报错;null是一种特殊的object;NaN是一种特殊的number;undeclared 是未声明也未赋值的变量,JavaScript访问会报错。
二十、在什么时候你会使用 document.write()?
DOM方法,可向文档写入 HTML 表达式或 JavaScript 代码。
二十一、如何实现下列代码:[1,2,3,4,5].duplicator(); // [1,2,3,4,5,1,2,3,4,5]
Array.prototype.duplicator = function(){ var l = this.length,i; for(i=0;i<l;i++){ this.push(this[i]) } }
二十二、解释 function foo() {} 与 var foo = function() {} 用法的区别
函数声明的两种方法:
var foo = function () {}
这种方式是声明了个变量,而这个变量是个方法,变量在js中是可以改变的。
也:将一个匿名函数赋值给了变量。
function foo() {}
这种方式是声明了个方法,foo这个名字无法改变
二十三、请解释可变 (mutable) 和不变 (immutable) 对象的区别。
在 JavaScript 中,对象是引用类型的数据,其优点在于频繁的修改对象时都是在原对象的基础上修改,并不需要重新创建,这样可以有效的利用内存,不会造成内存空间的浪费,对象的这种特性可以称之为 Mutable,中文的字面意思是「可变」。
Immutable 从字面上翻译成中文是「不可变」。每次修改一个 Immutable 对象时都会创建一个新的不可变的对象,在新对象上操作并不会影响到原对象的数据。
二十四、使用 Promises 而非回调 (callbacks) 优缺点是什么?
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
Promise也有一些缺点。
首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。
其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
二十五、请解释同步 (synchronous) 和异步 (asynchronous) 函数的区别。
同步调用,在发起一个函数或方法调用时,没有得到结果之前,该调用就不返回,直到返回结果;
异步调用的概念和同步相对,在一个异步调用发起后,被调用者立即返回给调用者,但调用者不能立刻得到结果,被调用者在实际处理这个调用的请求完成后,通过状态、通知或回调等方式来通知调用者请求处理的结果。
简单地说,同步就是发出一个请求后什么事都不做,一直等待请求返回后才会继续做事;异步就是发出请求后继续去做其他事,这个请求处理完成后会通知你,这时候就可以处理这个回应了。
二十六、你使用哪些工具和技术来调试 JavaScript 代码?
1.javascript的debugger语句
需要调试js的时候,我们可以给需要调试的地方通过debugger打断点,代码执行到断点就会暂定,这时候通过单步调试等方式就可以调试js代码
if (waldo) { debugger; }
这时候打开console面板,就可以调试了
2.DOM断点
DOM断点是一个Firebug和chrome DevTools提供的功能,当js需要操作打了断点的DOM时,会自动暂停,类似debugger调试。
使用DOM断点步骤:
选择你要打断点的DOM节点
右键选择Break on..
选择断点类型
另外的调试方法例如alert, console.log,查看元素等就不再赘述了。
二十七、你会使用怎样的语言结构来遍历对象属性 (object properties) 和数组内容?
for in 语句
一般for循环
数组forEach方法
以上がJavaScrip の面接でよくある質問と回答のまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。