Rumah > Artikel > hujung hadapan web > Ringkasan temuduga 10,000 perkataan JavaScript
Artikel ini membawakan anda pengetahuan yang berkaitan tentang JavaScript terutamanya ringkasan beberapa soalan temu bual biasa. Saya harap ia dapat membantu semua orang.
[Cadangan berkaitan: Tutorial video JavaScript, bahagian hadapan web]
1.1 Apakah jenis data yang terdapat dalam Js
Terdapat lapan jenis data dalam JavaScript
Jenis data asas: Tidak ditentukan , Null, Boolean, Nombor, Rentetan, Simbol, BigInt.
Jenis data kompleks: Objek
Simbol dan BigInt ialah jenis data baharu dalam ES6:
Simbol mewakili unik dan tidak berubah selepas jenis data penciptaan, yang adalah terutamanya untuk menyelesaikan masalah kemungkinan konflik global yang berubah-ubah.
BigInt ialah jenis data berangka yang boleh mewakili integer dalam mana-mana format ketepatan BigInt boleh digunakan untuk menyimpan dan mengendalikan integer besar dengan selamat, walaupun bilangan itu melebihi apa yang boleh diwakili oleh Nombor. julat integer yang selamat.
1.2 Bercakap tentang pemahaman anda tentang kawasan longgokan dan kawasan tindanan
Dalam sistem pengendalian, memori dibahagikan ke Untuk kawasan tindanan dan kawasan timbunan
memori kawasan tindanan secara automatik diperuntukkan dan dikeluarkan oleh pengkompil untuk menyimpan nilai parameter fungsi, nilai pembolehubah setempat, dsb. Ia beroperasi seperti timbunan dalam struktur data.
Memori kawasan timbunan biasanya diperuntukkan dan dikeluarkan oleh pembangun Jika pembangun tidak melepaskannya, ia mungkin dituntut semula oleh mekanisme kutipan sampah pada akhir program.
Dalam struktur data:
Dalam struktur data, kaedah capaian data dalam tindanan ialah pertama masuk, terakhir keluar.
Timbunan ialah baris gilir keutamaan, yang diisih mengikut keutamaan Keutamaan boleh ditentukan mengikut saiz.
Kaedah penyimpanan data
Jenis data asal disimpan terus dalam segmen data ringkas dalam timbunan, menduduki ruang kecil dan saiz tetap , adalah data yang kerap digunakan, jadi ia disimpan pada tindanan; . Jika disimpan pada tindanan, ia akan menjejaskan prestasi program; jenis data rujukan menyimpan penunjuk pada tindanan, yang menunjuk ke alamat permulaan entiti dalam timbunan. Apabila jurubahasa mencari nilai rujukan, ia mula-mula mendapatkan semula alamatnya pada tindanan dan kemudian memperoleh entiti daripada timbunan.
Maka kaedah menilai jenis data secara amnya boleh melalui: typeof, Empat kaedah yang biasa digunakan: instanceof, constructor dan toString
1.4 Apakah cara untuk menilai tatasusunan
Hakim melalui Object.prototype.toString.call()
Hakim melalui rantaian prototaip
Gunakan ES6 Array .isArray() membuat pertimbangan
membuat penghakiman melalui instanceof
oleh Array.prototype.isPrototypeOf
Pertama sekali, Undefined dan Null ialah jenis data asas mempunyai hanya satu nilai masing-masing, yang tidak ditentukan dan nol. undefined bermaksud tidak ditentukan, dan null bermaksud objek kosong. Umumnya, undefined akan dikembalikan apabila pembolehubah diisytiharkan tetapi tidak ditakrifkan terutamanya digunakan untuk menetapkan nilai kepada beberapa pembolehubah yang mungkin mengembalikan objek sebagai permulaan.
undefined bukanlah perkataan terpelihara dalam JavaScript, yang bermaksud anda boleh menggunakan undefined sebagai nama pembolehubah, tetapi ini sangat berbahaya dan akan menjejaskan pertimbangan nilai yang tidak ditentukan. Kita boleh mendapatkan nilai selamat yang tidak ditentukan melalui beberapa kaedah, seperti void 0.
Apabila menggunakan typeof untuk menilai kedua-dua jenis ini, Null typing akan mengembalikan "objek", yang merupakan masalah sejarah. Mengembalikan benar apabila menggunakan tanda sama dua untuk membandingkan dua jenis nilai dan mengembalikan salah apabila menggunakan tanda sama tiga.
1.6 Apakah hasil jenis null dan mengapa?
Hasil jenis null ialah Objek. Dalam versi pertama JavaScript, semua nilai disimpan dalam unit 32-bit, setiap unit mengandungi teg jenis kecil (1-3 bit) dan data sebenar nilai semasa yang akan disimpan. Label jenis disimpan dalam bit rendah setiap unit, dan terdapat lima jenis data:
000: object - 当前存储的数据指向一个对象。 1: int - 当前存储的数据是一个 31 位的有符号整数。 010: double - 当前存储的数据指向一个双精度的浮点数。 100: string - 当前存储的数据指向一个字符串。 110: boolean - 当前存储的数据是布尔值。
Jika bit terendah ialah 1, panjang bendera label jenis hanya satu bit; jika bit terendah ialah 0, panjang bendera label jenis ialah tiga bit, memberikan ruang tambahan untuk menyimpan yang lain. empat jenis data. Panjang dua bit.
mempunyai dua jenis data khas:
Nilai undefined ialah (-2)30 (nombor di luar julat integer);
1.7 Mengapa 0.1 0.2 ! == 0.3, bagaimana untuk menjadikannya sama (ketepatan hilang)Komputer menyimpan data dalam binari , jadi apabila komputer mengira 0.1 0.2, ia sebenarnya mengira jumlah binari dua nombor.
Hanya terdapat satu jenis nombor dalam JS: Nombor Pelaksanaannya mengikut piawaian IEEE 754 dan menggunakan panjang tetap 64-bit untuk mewakilinya, iaitu nombor titik terapung berketepatan dua kali standard. Dalam tatatanda saintifik binari, bahagian perpuluhan nombor titik terapung berketepatan dua hanya boleh mengekalkan sehingga 52 digit Ditambah 1 sebelumnya, ia sebenarnya mengekalkan 53 digit yang bererti perlu dibuang dan ikuti "0 pembundaran ke 1" prinsip. pada dasarnya.
Mengikut prinsip ini, menambah nombor perduaan 0.1 dan 0.2 dan menukarkannya kepada nombor perpuluhan ialah: 0.300000000000000004. Jadi penyelesaian untuk tidak sama
adalah dengan menetapkan margin ralat, sering dipanggil "ketepatan mesin". Untuk JavaScript, nilai ini biasanya 2-52 Dalam ES6, atribut Number.EPSILON disediakan, dan nilainya ialah 2-52 Anda hanya perlu menentukan sama ada 0.1 0.2-0.3 adalah kurang daripada Number.EPSILON kurang, anda boleh Ia dinilai sebagai 0.1 0.2 ===0.3
function numberepsilon(arg1,arg2){ return Math.abs(arg1 - arg2) < Number.EPSILON; } console.log(numberepsilon(0.1 + 0.2, 0.3)); // true
1.8 Bagaimana untuk mendapatkan nilai yang tidak ditentukan yang selamat? Oleh kerana undefined ialah pengecam, ia boleh digunakan dan ditetapkan sebagai pembolehubah, tetapi ini akan menjejaskan pertimbangan biasa undefined. Ungkapan void ___ tidak mempunyai nilai pulangan, jadi hasilnya tidak ditentukan. void tidak mengubah hasil ungkapan, ia hanya menyebabkan ungkapan tidak mengembalikan nilai. Jadi anda boleh menggunakan void 0 untuk mendapatkan undefined.
1.9 Apakah keputusan jenis NaN? NaN bermaksud "bukan nombor". NaN ialah "nilai sentinel" (nilai sentinel, nilai biasa dengan tujuan khas), yang digunakan untuk menunjukkan bahawa nombor itu Ralat. syarat ialah "Melaksanakan operasi matematik tanpa kejayaan, ini adalah hasil yang dikembalikan selepas kegagalan".
NaN ialah nilai istimewa yang tidak sama dengan dirinya dan merupakan satu-satunya nilai bukan refleksif. Apa yang dipanggil ireflexive bermakna NaN tidak sama dengan sesiapa, termasuk dirinya sendiri, tetapi dalam NaN! = NaN akan kembali benartypeof NaN; // "number"
1.10 Apakah perbezaan antara fungsi isNaN dan Number.isNaN? Selepas fungsi isNaN menerima parameter, ia akan cuba menukar parameter kepada nilai berangka Sebarang nilai yang tidak boleh ditukar kepada nilai berangka akan kembali benar, jadi jika bukan -nilai angka diluluskan dalam, ia juga akan kembali benar, akan menjejaskan pertimbangan NaN.
Fungsi Number.isNaN terlebih dahulu akan menentukan sama ada parameter masuk ialah nombor, ia akan terus menentukan sama ada penukaran jenis data tidak akan dilakukan tepat untuk penghakiman NaN.
1.11 Apakah peraturan cast untuk operator ==? Untuk ==, jika jenis kedua-dua bahagian perbandingan berbeza, penukaran jenis akan dilakukan. Jika x dan y dibandingkan untuk melihat sama ada ia adalah sama, proses penghakiman berikut akan dijalankan:
Pertama, ia akan dinilai sama ada kedua-dua jenis adalah sama, iaitu saiz kedua-duanya akan dibandingkan;
Jika jenisnya tidak sama, penukaran jenis akan dilakukan dahulu; return true.
akan menentukan sama ada kedua-dua jenis adalah rentetan dan nombor Jika ya, ia akan menukar aksara Tukar rentetan kepada nombor
untuk menentukan sama ada salah satu pihak adalah. boolean. Jika ya, boolean akan ditukar menjadi nombor dan kemudian menilai1 == '1' ↓ 1 == 1untuk menentukan sama ada salah satu pihak adalah objek dan pihak yang satu lagi Ia adalah rentetan, nombor atau simbol , objek akan ditukar kepada jenis asal dan kemudian dinilai
'1' == true ↓ '1' == 1 ↓ 1 == 1Carta alir adalah seperti berikut:
'1' == { name: 'js' } ↓'1' == '[object Object]'
1.12 Apakah peraturan penukaran untuk menukar jenis nilai lain kepada rentetan?
Jenis Null dan Undefined, null ditukar kepada "null", undefined ditukar kepada "undefined", Jenis Boolean, true ditukar kepada "true", palsu ditukar kepada "palsu".
Nilai jenis nombor ditukar secara langsung, tetapi nombor yang sangat kecil dan besar itu menggunakan bentuk eksponen.
Nilai jenis simbol ditukar secara langsung, tetapi hanya hantaran eksplisit dibenarkan Penggunaan hantaran tersirat akan menghasilkan ralat.
对普通对象来说,除非自行定义 toString() 方法,否则会调用 toString()(Object.prototype.toString())来返回内部属性 [[Class]] 的值,如"[object Object]"。如果对象有自己的 toString() 方法,字符串化时就会调用该方法并使用其返回值。
1.13. 其他值类型转成数字的转换规则?
Undefined 类型的值转换为 NaN。
Null 类型的值转换为 0。
Boolean 类型的值,true 转换为 1,false 转换为 0。
String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。
Symbol 类型的值不能转换为数字,会报错。
对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。
为了将值转换为相应的基本类型值, 隐式转换会首先检查该值是否有valueOf()方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。
如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。
1.14 其他值类型转成布尔类型的转换规则?
以下这些是假值: undefined 、 null 、 false 、 +0、-0 和 NaN 、 ""
假值的布尔强制类型转换结果为 false。从逻辑上说,假值列表以外的都应该是真值。
1.15. || 和 && 操作符的返回值?
|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先强制转换为布尔类型,然后再执行条件判断。
对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。
&& 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。
|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果
1.16. Object.is() 与比较操作符 “===”、“==” 的区别?
使用双等号(==)进行相等判断时,如果两边的类型不一致,则会进行强制类型转化后再进行比较。
使用三等号(===)进行相等判断时,如果两边的类型不一致时,不会做强制类型准换,直接返回 false。
使用 Object.is 来进行相等判断时,一般情况下和三等号的判断相同,它处理了一些特殊的情况,比如 -0 和 +0 不再相等,两个 NaN 是相等的。
1.17. 什么是 JavaScript 中的包装类型?
在 JavaScript 中,基本类型是没有属性和方法的,但是为了便于操作基本类型的值,在调用基本类型的属性或方法时 JavaScript 会在后台隐式地将基本类型的值转换为对象。如:
const a = "abc"; a.length; // 3
在访问'abc'.length时,JavaScript 将'abc'在后台转换成String('abc'),然后再访问其length属性。
1.18 Js中隐式转换规则
在 if 语句、逻辑语句、数学运算逻辑、== 等情况下都可能出现隐式类型转换。
坑: 判断时, 尽量不要用 = = , 要用 = = = ( 两个等号判断, 如果类型不同, 默认会进行隐式类型转换再比较)
1.19 说说你对this的理解
this是一个在运行时才进行绑定的引用,在不同的情况下它可能会被绑定不同的对象。
1.20 如何判断 this 的指向
第一种是函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。
第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this 指向这个对象。
第三种是构造器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象。
第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。其中 apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。也就是说,在使用 call() 方法时,传递给函数的参数必须逐个列举出来。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。
this绑定的优先级
new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级
1.21 Map和Object的区别
1.22 说说你对JSON的理解
JSON 是一种基于文本的轻量级的数据交换格式。它可以被任何的编程语言读取和作为数据格式来传递。
在项目开发中,使用 JSON 作为前后端数据交换的方式。在前端通过将一个符合 JSON 格式的数据结构序列化为 JSON 字符串,然后将它传递到后端,后端通过 JSON 格式的字符串解析后生成对应的数据结构,以此来实现前后端数据的一个传递。
因为 JSON 的语法是基于 js 的,因此很容易将 JSON 和 js 中的对象弄混,但是应该注意的是 JSON 和 js 中的对象不是一回事,JSON 中对象格式更加严格,比如说在 JSON 中属性值不能为函数,不能出现 NaN 这样的属性值等,因此大多数的 js 对象是不符合 JSON 对象的格式的。
在 js 中提供了两个函数来实现 js 数据结构和 JSON 格式的转换处理,
JSON.stringify 函数,通过传入一个符合 JSON 格式的数据结构,将其转换为一个 JSON 字符串。如果传入的数据结构不符合 JSON 格式,那么在序列化的时候会对这些值进行对应的特殊处理,使其符合规范。在前端向后端发送数据时,可以调用这个函数将数据对象转化为 JSON 格式的字符串。
JSON.parse() 函数,这个函数用来将 JSON 格式的字符串转换为一个 js 数据结构,如果传入的字符串不是标准的 JSON 格式的字符串的话,将会抛出错误。当从后端接收到 JSON 格式的字符串时,可以通过这个方法来将其解析为一个 js 数据结构,以此来进行数据的访问。
1.222 String和JSON.stringify的区别
console.log(String("abc")); // abc console.log(JSON.stringify("abc")); // "abc" console.log(String({ key: "value" })); // [object Object] console.log(JSON.stringify({ key: "value" })); // {"key":"value"} console.log(String([1, 2, 3])); // 1,2,3 console.log(JSON.stringify([1, 2, 3])); // [1,2,3] const obj = { title: "devpoint", toString() { return "obj"; }, }; console.log(String(obj)); // obj console.log(JSON.stringify(obj)); // {"title":"devpoint"}
当需要将一个数组和一个普通对象转换为字符串时,经常使用JSON.stringify。
如果需要对象的toString方法被重写,则需要使用String()。
在其他情况下,使用String()将变量转换为字符串。
1.23 什么是伪数组(类数组)
一个拥有 length 属性和若干索引属性的对象就可以被称为类数组对象,类数组对象和数组类似,但是不能调用数组的方法。
常见的类数组对象有 arguments 和 DOM 方法的返回结果,还有一个函数也可以被看作是类数组对象,因为它含有 length 属性值,代表可接收的参数个数。
1.24 类数组转换成数组的方法有哪些
常见的类数组转换为数组的方法有这样几种:
通过 call 调用数组的 slice 方法来实现转换
Array.prototype.slice.call(arrayLike);
通过 call 调用数组的 splice 方法来实现转换
Array.prototype.splice.call(arrayLike, 0);
通过 apply 调用数组的 concat 方法来实现转换
Array.prototype.concat.apply([], arrayLike);
通过 Array.from 方法来实现转换
Array.from(arrayLike);
1.25 Unicode、UTF-8、UTF-16、UTF-32的区别?
Unicode 是编码字符集(字符集),而UTF-8、UTF-16、UTF-32是字符集编码(编码规则);
UTF-16 使用变长码元序列的编码方式,相较于定长码元序列的UTF-32算法更复杂,甚至比同样是变长码元序列的UTF-8也更为复杂,因为其引入了独特的代理对这样的代理机制;
UTF-8需要判断每个字节中的开头标志信息,所以如果某个字节在传送过程中出错了,就会导致后面的字节也会解析出错;而UTF-16不会判断开头标志,即使错也只会错一个字符,所以容错能力教强;
如果字符内容全部英文或英文与其他文字混合,但英文占绝大部分,那么用UTF-8就比UTF-16节省了很多空间;而如果字符内容全部是中文这样类似的字符或者混合字符中中文占绝大多数,那么UTF-16就占优势了,可以节省很多空间;
1.26 常见的位运算符有哪些?其计算规则是什么?
现代计算机中数据都是以二进制的形式存储的,即0、1两种状态,计算机对二进制数据进行的运算加减乘除等都是叫位运算,即将符号位共同参与运算的运算。
常见的位运算有以下几种:
1.27 为什么函数的 arguments 参数是类数组而不是数组?如何遍历类数组?
arguments是一个对象,它的属性是从 0 开始依次递增的数字,还有callee和length等属性,与数组相似;但是它却没有数组常见的方法属性,如forEach, reduce等,所以叫它们类数组。
要遍历类数组,有三个方法:
(1)将数组的方法应用到类数组上,这时候就可以使用call和apply方法,如:
function foo(){ Array.prototype.forEach.call(arguments, a => console.log(a)) }
(2)使用Array.from方法将类数组转化成数组:
function foo(){ const arrArgs = Array.from(arguments) arrArgs.forEach(a => console.log(a)) }
(3)使用展开运算符将类数组转化成数组
function foo(){ const arrArgs = [...arguments] arrArgs.forEach(a => console.log(a)) }
1.28 escape、encodeURI、encodeURIComponent 的区别
encodeURI 是对整个 URI 进行转义,将 URI 中的非法字符转换为合法字符,所以对于一些在 URI 中有特殊意义的字符不会进行转义。
encodeURIComponent 是对 URI 的组成部分进行转义,所以一些特殊字符也会得到转义。
escape 和 encodeURI 的作用相同,不过它们对于 unicode 编码为 0xff 之外字符的时候会有区别,escape 是直接在字符的 unicode 编码前加上 %u,而 encodeURI 首先会将字符转换为 UTF-8 的格式,再在每个字节前加上 %。
1.29 什么是尾调用,使用尾调用有什么好处?
尾调用指的是函数的最后一步调用另一个函数。代码执行是基于执行栈的,所以当在一个函数里调用另一个函数时,会保留当前的执行上下文,然后再新建另外一个执行上下文加入栈中。使用尾调用的话,因为已经是函数的最后一步,所以这时可以不必再保留当前的执行上下文,从而节省了内存,这就是尾调用优化。
但是 ES6 的尾调用优化只在严格模式下开启,正常模式是无效的。
1.30 use strict是什么? 它有什么用?
use strict 是一种 ECMAscript5 添加的(严格模式)运行模式,这种模式使得 Javascript 在更严格的条件下运行。设立严格模式的目的如下:
消除 Javascript 语法的不合理、不严谨之处,减少怪异行为;
消除代码运行的不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
为未来新版本的 Javascript 做好铺垫。
区别:
禁止使用 with 语句。
禁止 this 关键字指向全局对象。
对象不能有重名的属性。
1.31 如何判断一个对象是否属于某个类?
第一种方式,使用 instanceof 运算符来判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。
第二种方式,通过对象的 constructor 属性来判断,对象的 constructor 属性指向该对象的构造函数,但是这种方式不是很安全,因为 constructor 属性可以被改写。
第三种方式,如果需要判断的是某个内置的引用类型的话,可以使用 Object.prototype.toString() 方法来打印对象的[[Class]] 属性来进行判断。
1.32 强类型语言和弱类型语言的区别
强类型语言:强类型语言也称为强类型定义语言,是一种总是强制类型定义的语言,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。Java和C++等语言都是强制类型定义的,也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。例如你有一个整数,如果不显式地进行转换,你不能将其视为一个字符串。
Bahasa yang ditaip dengan lemah: Bahasa yang ditaip dengan lemah juga dipanggil bahasa definisi ditaip lemah, iaitu bertentangan dengan definisi yang ditaip dengan kuat. Bahasa JavaScript ialah bahasa yang ditaip lemah. Secara mudah difahami, ia adalah bahasa yang jenis pembolehubah boleh diabaikan. Sebagai contoh, JavaScript ditaip dengan lemah Dalam JavaScript, anda boleh menggabungkan rentetan '12' dan integer 3 untuk mendapatkan rentetan '123' dan penukaran jenis paksa akan dilakukan apabila menambah.
Perbandingan kedua-duanya: Bahasa yang ditaip kuat mungkin lebih perlahan sedikit daripada bahasa yang ditaip lemah, tetapi ketegasan yang dibawa oleh bahasa yang ditaip kuat dapat membantu mengelakkan banyak ralat.
1.33 Perbezaan antara bahasa yang ditafsir dan bahasa yang disusun
(1) Bahasa yang ditafsir menggunakan jurubahasa khusus untuk mentafsir program sumber baris demi baris Ditafsirkan ke dalam kod mesin khusus platform dan dilaksanakan serta-merta. Kod diterjemahkan secara dinamik dan dilaksanakan baris demi baris oleh jurubahasa apabila ia dilaksanakan, dan bukannya diterjemahkan sebelum pelaksanaan. Bahasa yang ditafsirkan tidak perlu disusun terlebih dahulu Mereka secara langsung mentafsir kod sumber ke dalam kod mesin dan melaksanakannya dengan segera, jadi selagi platform tertentu menyediakan penterjemah yang sepadan, program itu boleh dijalankan. Ciri-cirinya diringkaskan seperti berikut
Setiap kali bahasa yang ditafsirkan dijalankan, kod sumber perlu ditafsirkan ke dalam kod mesin dan dilaksanakan, yang tidak cekap
Selagi platform menyediakan penterjemah yang sepadan, kod sumber boleh dijalankan kod, jadi pemindahan program sumber boleh dipermudahkan;
JavaScript, Python, dll.
(2) Bahasa yang disusun menggunakan pengkompil khusus untuk menyusun kod sumber bahasa peringkat tinggi ke dalam kod mesin yang boleh dilaksanakan oleh perkakasan platform pada satu masa untuk platform tertentu, dan membungkusnya ke dalam kod mesin yang boleh dilaksanakan oleh perkakasan platform Mengenal pasti format program boleh laku. Sebelum atur cara yang ditulis dalam bahasa yang dikompilasi dilaksanakan, proses kompilasi khas diperlukan untuk menyusun kod sumber ke dalam fail bahasa mesin, seperti fail format exe Apabila dijalankan pada masa hadapan, anda boleh terus menggunakan hasil kompilasi, seperti sebagai menjalankan exe secara langsung. Kerana ia hanya perlu dikompilasi sekali dan tidak perlu dikompilasi apabila dijalankan nanti, bahasa yang dikompilasi mempunyai kecekapan pelaksanaan yang tinggi. Ciri-cirinya diringkaskan seperti berikut:
Ia disusun ke dalam fail bahasa mesin yang berkaitan dengan platform pada satu masa, dan dipisahkan daripada persekitaran pembangunan apabila berjalan, dengan kecekapan operasi yang tinggi; berkaitan dengan platform tertentu dan secara amnya tidak boleh dipindahkan ke platform lain ;
C, C, dsb. ialah bahasa yang disusun.
Perbezaan utama antara kedua-duanya ialah: program sumber yang terdahulu boleh dijalankan pada platform selepas penyusunan, manakala yang terakhir disusun semasa operasi. Oleh itu, yang pertama berjalan pantas dan yang kedua mempunyai prestasi merentas platform yang baik.
1.34 Perbezaan antara for...in dan for...of for...of ialah kaedah traversal baharu dalam ES6 yang membenarkan Traverse struktur data (tatasusunan, objek, dsb.) yang mengandungi antara muka iterator dan mengembalikan nilai setiap item Perbezaan dari for...in dalam ES3 adalah seperti berikut
untuk... traversal memperoleh nilai kunci objek, kerana …in memperoleh nama kunci objek
kerana… dalam akan merentasi keseluruhan rantaian prototaip objek, prestasinya sangat lemah dan tidak disyorkan, manakala untuk…daripada hanya melintasi objek semasa dan tidak melintasi rantai prototaip
Untuk traversal tatasusunan, untuk…in akan mengembalikan semua sifat terhitung dalam tatasusunan (termasuk sifat terhitung pada rantai prototaip), manakala untuk …dari hanya mengembalikan nilai sifat yang sepadan dengan subskrip tatasusunan; boleh digunakan untuk melintasi tatasusunan, objek seperti tatasusunan, rentetan, Set, Peta dan objek Penjana.
1.35 Perbezaan antara ajax, axios dan fetch
(1) AJAX Ajax ialah "AsynchronousJavascriptAndXML" (JavaScript dan XML tak segerak), yang bermaksud Teknologi pembangunan web untuk mencipta aplikasi web interaktif. Ia adalah teknologi yang boleh mengemas kini bahagian halaman web tanpa memuatkan semula keseluruhan halaman. Ajax membenarkan halaman web untuk mengemas kini secara tak segerak dengan menukar sejumlah kecil data dengan pelayan di latar belakang. Ini bermakna bahagian halaman web boleh dikemas kini tanpa memuatkan semula keseluruhan halaman. Halaman web tradisional (tidak menggunakan Ajax) mesti memuat semula keseluruhan halaman web jika kandungan perlu dikemas kini. Kelemahannya adalah seperti berikut:
Ia direka untuk pengaturcaraan MVC dan tidak mematuhi trend MVVM bahagian hadapan
Berasaskan pada pembangunan XHR asli, seni bina XHR itu sendiri tidak Jelas
Tidak mematuhi prinsip Pengasingan Kebimbangan
Konfigurasi dan kaedah panggilan sangat mengelirukan, dan model tak segerak berasaskan acara tidak mesra.
(2) Fetch fetch dikenali sebagai pengganti AJAX Ia muncul dalam ES6 dan menggunakan objek janji dalam ES6. Fetch direka berdasarkan janji. Struktur kod Fetch jauh lebih mudah daripada ajax. Ambil bukan enkapsulasi lanjut ajax, tetapi js asli, yang tidak menggunakan objek XMLHttpRequest.
Sintaks mudah, lebih semantik
Berdasarkan pelaksanaan Promise standard, menyokong penyegerakan/menunggu
Ia lebih rendah dan menyediakan API yang kaya (permintaan, tindak balas)
Ia dipisahkan daripada XHR dan merupakan kaedah pelaksanaan baharu dalam spesifikasi ES
Kelemahan pengambilan:
mengambil hanya ralat laporan untuk permintaan rangkaian 400 dan 500 dianggap sebagai permintaan yang berjaya Apabila pelayan mengembalikan 400 dan 500 kod ralat, ia tidak akan ditolak Hanya apabila ralat rangkaian menyebabkan permintaan itu gagal diselesaikan, pengambilan akan ditolak.
fetch tidak membawa kuki secara lalai, anda perlu menambah item konfigurasi: fetch(url, {credentials: 'include'})
fetch tidak Menyokong pengguguran, tetapi tidak menyokong kawalan tamat masa yang dilaksanakan menggunakan setTimeout dan Promise.reject tidak boleh menghalang proses permintaan daripada terus berjalan di latar belakang, mengakibatkan pembaziran trafik
1.37 Apakah perbezaan antara forEach dan kaedah peta?
Kaedah ini digunakan Apabila melintasi tatasusunan, perbezaan antara keduanya adalah seperti berikut:
kaedah untukEach() akan melaksanakan fungsi yang disediakan untuk setiap elemen, dan operasi pada data akan menukar tatasusunan asal Kaedah ini tidak mempunyai nilai pulangan; nilai dalam tatasusunan baharu ialah nilai selepas tatasusunan asal diproses dengan memanggil fungsi itu; >Salinan cetekSalinan cetek merujuk kepada penciptaan data baharu, yang mempunyai salinan tepat nilai atribut data asal
Jika atribut adalah daripada jenis asas, nilai jenis asas disalin. Jika atribut ialah jenis rujukan, alamat memori disalin
, iaitu, salinan cetek menyalin satu lapisan, dan jenis rujukan dalam berkongsi alamat memori
Salinan cetek biasa:
Object.assign
Object.create
slice
concat()
Kembangkan operator
Deep copy
Kaedah salinan dalam yang biasa ialah:
_.cloneDeep()
jQuery.extend()
JSON.stringify()
Rekursi gelung tulisan tangan
Jika terdapat RegExp dalam obj, ia akan dicetak sebagai objek kosong
Jika terdapat objek dalam json yang dihasilkan oleh pembina, pembinaan objek akan dibuang
1.40 Tahu lodash ? Apakah API biasa yang ada padanya? Lodash ialah perpustakaan utiliti JavaScript yang konsisten, modular dan berprestasi tinggi.
_.cloneDeep copy
_.reject mengalih keluar elemen berdasarkan syarat.
_.drop(array, [n=1] ) Fungsi: Keluarkan n elemen pertama dalam tatasusunan, dan kemudian kembalikan bahagian yang tinggal.
1.41 LHS dan Pertanyaan RHS LHS (Sebelah Kiri) dan RHS (Sebelah Kanan) ialah dua cara untuk enjin JS mengendalikan pembolehubah semasa fasa pelaksanaan kod Perbezaan antara keduanya ialah Tujuan pertanyaan berubah adalah tugasan atau pertanyaan berubah.
LHS boleh difahami sebagai pembolehubah di sebelah kiri pengendali penetapan (=), contohnya, a = 1. Tujuan carian enjin semasa untuk pembolehubah a ialah penetapan pembolehubah. Dalam kes ini, enjin tidak peduli apa nilai asal pembolehubah a, ia hanya memberikan nilai 1 kepada pembolehubah a.
RHS boleh difahami sebagai pembolehubah di sebelah kanan pengendali tugasan (=), contohnya: console.log(a), di mana tujuan carian enjin untuk pembolehubah a adalah untuk bertanya, dan ia perlu mencari nilai sebenar yang sepadan dengan pembolehubah a Apakah nilai sebelum ia boleh dicetak.
1.42 Bagaimanakah termasuk lebih baik daripada indexOf?
termasuk boleh mengesan NaN, indexOf tidak dapat mengesan NaN, termasuk penggunaan Number.isNaN secara dalaman untuk memadankan NaN
1.43 AMD dan CMD Perbezaannya?
1.44 (a == 1 && a == 2 && a == 3) Adakah mungkin untuk menjadi benar ?
方案一:重写toString()或valueOf()
let a = { i: 1, toString: function () { return a.i++; } } console.log(a == 1 && a == 2 && a == 3); // true
方案二:数组
数组的toString接口默认调用数组的join方法,重写join方法。定义a为数字,每次比较时就会调用 toString()方法,我们把数组的shift方法覆盖toString即可:
let a = [1,2,3]; a.toString = a.shift; console.log(a == 1 && a == 2 && a == 3); // true
当然把toString改为valueOf也是一样效果:
let a = [1,2,3]; a. valueOf = a.shift; console.log(a == 1 && a == 2 && a == 3); // true
方案三:使用Object.defineProperty()
Object.defineProperty()用于定义对象中的属性,接收三个参数:object对象、对象中的属性,属性描述符。属性描述符中get:访问该属性时自动调用。
var _a = 1; Object.defineProperty(this,'a',{ get:function(){ return _a++ } }) console.log(a===1 && a===2 && a===3)//true
1.45 JS中的 MUL 函数
MUL表示数的简单乘法。在这种技术中,将一个值作为参数传递给一个函数,而该函数将返回另一个函数,将第二个值传递给该函数,然后重复继续。例如:xyz可以表示为
const mul = x => y => z => x * y * z console.log(mul(1)(2)(3)) // 6
1.46 深度遍历广度遍历的区别?
对于算法来说 无非就是时间换空间 空间换时间
1、深度优先不需要记住所有的节点, 所以占用空间小, 而广度优先需要先记录所有的节点占用空间大
2、深度优先有回溯的操作(没有路走了需要回头)所以相对而言时间会长一点
3、深度优先采用的是堆栈的形式, 即先进后出
4、广度优先则采用的是队列的形式, 即先进先出
1.47 JS中的设计模式有哪些?
单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。实现的方法为先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
策略模式
定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。
代理模式
为一个对象提供一个代用品或占位符,以便控制对它的访问。
中介者模式
通过一个中介者对象,其他所有的相关对象都通过该中介者对象来通信,而不是相互引用,当其中的一个对象发生改变时,只需要通知中介者对象即可。通过中介者模式可以解除对象与对象之间的紧耦合关系。
装饰者模式
在不改变对象自身的基础上,在程序运行期间给对象动态地添加方法。
1.48 forEach如何跳出循环?
forEach是不能通过break或者return来实现跳出循环的,为什么呢?实现过forEach的同学应该都知道,forEach的的回调函数形成了一个作用域,在里面使用return并不会跳出,只会被当做continue
可以利用try catch
function getItemById(arr, id) { var item = null; try { arr.forEach(function (curItem, i) { if (curItem.id == id) { item = curItem; throw Error(); } }) } catch (e) { } return item; }
1.49 JS中如何将页面重定向到另一个页面?
1、使用 location.href:window.location.href ="url"
2、使用 location.replace: window.location.replace("url");
1.50 移动端如何实现上拉加载,下拉刷新?
上拉加载
上拉加载的本质是页面触底,或者快要触底时的动作
判断页面触底我们需要先了解一下下面几个属性
scrollTop:滚动视窗的高度距离window顶部的距离,它会随着往上滚动而不断增加,初始值是0,它是一个变化的值
clientHeight:它是一个定值,表示屏幕可视区域的高度;
scrollHeight:页面不能滚动时也是存在的,此时scrollHeight等于clientHeight。scrollHeight表示body所有元素的总长度(包括body元素自身的padding)
综上我们得出一个触底公式:
scrollTop + clientHeight >= scrollHeight
下拉刷新
下拉刷新的本质是页面本身置于顶部时,用户下拉时需要触发的动作
关于下拉刷新的原生实现,主要分成三步:
监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY;
监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;
监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置
1.51 JS 中的数组和函数在内存中是如何存储的?
Storan tatasusunan dalam JavaScript perlu dibahagikan secara kasar kepada dua situasi:
Tasusunan dengan jenis data yang sama memperuntukkan ruang memori berterusan
Tasusunan dengan jenis penggunaan data yang tidak sama Pemetaan pencincangan dan memperuntukkan ruang memori
Peringatan hangat: Anda boleh bayangkan bahawa ruang ingatan berterusan hanya perlu mengira terus lokasi storan berdasarkan indeks (penunjuk). Jika ia adalah peta cincang, anda perlu mengira nilai indeks terlebih dahulu, dan kemudian jika terdapat konflik dalam nilai indeks, anda perlu melakukan carian kedua (anda perlu tahu bagaimana cincangan disimpan).
2.1 Apakah penutupan?
Kenyataan rasmi: Penutupan merujuk kepada fungsi yang mempunyai akses kepada pembolehubah dalam skop fungsi lain.
Pernyataan MDN: Penutupan ialah sejenis objek istimewa. Ia terdiri daripada dua bahagian: fungsi, dan persekitaran di mana fungsi itu dicipta. Persekitaran terdiri daripada sebarang pembolehubah tempatan yang berada dalam skop semasa penutupan dibuat.
Jawapan mendalam
Apabila penyemak imbas memuatkan halaman, ia akan meletakkan kod dalam memori tindanan (ECStack) untuk pelaksanaan Apabila fungsi ditolak ke dalam tindanan, konteks peribadi (EC) akan dijana Konteks ini boleh melindungi bahagian dalam Penggunaan pembolehubah (AO) tidak tertakluk kepada gangguan luaran, dan jika sesetengah kandungan dalam konteks pelaksanaan semasa diduduki oleh kandungan di luar konteks, konteks semasa tidak akan. dikeluarkan daripada timbunan, supaya pembolehubah dan nilai pembolehubah di dalamnya boleh disimpan, jadi saya fikir Penutupan adalah mekanisme untuk menyimpan dan melindungi pembolehubah peribadi dalaman.
2.2 Peranan penutupan
Penutupan mempunyai dua kegunaan biasa;
Penutupan pertama Tujuannya adalah untuk membolehkan kami untuk mengakses pembolehubah di dalam fungsi dari luar fungsi. Dengan menggunakan penutupan, anda boleh mengakses pembolehubah di dalam fungsi secara luaran dengan memanggil fungsi penutupan secara luaran. Anda boleh menggunakan kaedah ini untuk mencipta pembolehubah peribadi.
Satu lagi kegunaan penutupan adalah untuk membenarkan objek pembolehubah dalam konteks fungsi yang telah selesai dijalankan untuk kekal dalam ingatan Kerana fungsi penutupan mengekalkan rujukan kepada objek pembolehubah, objek pembolehubah tidak akan dikitar semula.
2.3 Rujukan senario penutupan dalam projek dan masalah yang mereka bawa
Dalam projek sebenar, penutupan akan digunakan untuk mengendalikan Balut kandungan modul yang anda tulis, supaya anda boleh melindungi kod anda sendiri sebagai peribadi dan mengelakkan konflik dengan pembolehubah global atau kod lain. Ini adalah untuk menggunakan mekanisme perlindungan.
Walau bagaimanapun, tidak disyorkan untuk menggunakan penutupan terlalu banyak, kerana menggunakan konteks yang tidak dikeluarkan memerlukan ruang memori tindanan, dan penggunaan yang berlebihan boleh menyebabkan kebocoran memori.
Cara untuk menyelesaikan masalah kebocoran memori yang disebabkan oleh penutupan adalah dengan melepaskan fungsi penutupan secara manual selepas menggunakannya.
2.4 Senario penggunaan penutupan
kembali fungsi
fungsi sebagai parameter
IIFE (Self -melaksanakan fungsi)
Penugasan gelung
Menggunakan fungsi panggil balik menggunakan penutupan
Pendikit dan anti goncang
Fungsi kari
2.5 Proses pelaksanaan penutupan
Bentuk konteks peribadi
Tolak ke tindanan untuk melaksanakan
Satu siri operasi
(1). Mulakan rantaian skop (kedua-duanya berakhir
(2) Inikan
(3) Inikan argumen
(4). Penetapan parameter formal
(5 promosi pembolehubah
(6) pelaksanaan kod
pertama kali memeriksa jika pembolehubah ditemui persendirian kepada anda. Jika ia bukan peribadi, cari mengikut rantaian skop Jika ia bukan yang unggul, teruskan mencari dalam talian sehingga EC(G) Pencarian pembolehubah sebenarnya adalah proses penyambungan rantaian skop. menyambung rantai pertanyaan Formulanya ialah rantai skop.
Dalam keadaan biasa, selepas pelaksanaan kod selesai, konteks peribadi muncul daripada timbunan dan dikitar semula. Walau bagaimanapun, dalam keadaan khas, jika sesuatu dalam konteks peribadi semasa diduduki oleh sesuatu selain daripada konteks pelaksanaan selepas pelaksanaan selesai, konteks peribadi semasa tidak akan dikeluarkan daripada tindanan, iaitu konteks yang tidak akan dimusnahkan terbentuk, penutupan.
2.6 Jenis konteks pelaksanaan
(1) Konteks pelaksanaan global
Apa-apa sahaja yang tidak berada di dalam fungsi ialah pelaksanaan global Konteks, ia mula-mula mencipta objek tetingkap global dan menetapkan nilai ini sama dengan objek global ini Hanya terdapat satu konteks pelaksanaan global dalam program.
(2) Konteks pelaksanaan fungsi
Apabila fungsi dipanggil, konteks pelaksanaan baharu akan dibuat untuk fungsi tersebut.
(3) konteks pelaksanaan fungsi eval
Kod yang dilaksanakan dalam fungsi eval akan mempunyai konteks pelaksanaannya sendiri, tetapi fungsi eval tidak biasa digunakan dan tidak akan diperkenalkan.
2.7 Apakah tindanan konteks pelaksanaan
Enjin JavaScript menggunakan tindanan konteks pelaksanaan untuk mengurus konteks pelaksanaan
Apabila JavaScript melaksanakan kod, ia mula-mula menemui kod global dan mencipta konteks pelaksanaan global dan menolaknya ke dalam tindanan pelaksanaan Setiap kali ia menghadapi panggilan fungsi, ia mencipta konteks pelaksanaan baharu untuk fungsi dan menolaknya ke dalam tindanan pelaksanaan. . Di bahagian atas tindanan, enjin akan melaksanakan fungsi yang terletak di bahagian atas tindanan konteks pelaksanaan Apabila pelaksanaan fungsi selesai, konteks pelaksanaan muncul dari tindanan dan terus melaksanakan konteks seterusnya. Apabila semua kod telah dilaksanakan, konteks pelaksanaan global muncul dari timbunan.
2.8 Tiga fasa konteks pelaksanaan
Fasa penciptaan → Fasa pelaksanaan → Fasa kitar semula
Fasa penciptaan
(1) pengikatan ini
Dalam konteks pelaksanaan global, ini menunjuk kepada objek global (objek tetingkap)
Dalam konteks pelaksanaan fungsi, titik ini bergantung pada cara fungsi dipanggil . Jika ia dipanggil oleh objek rujukan, maka ini akan ditetapkan kepada objek itu, jika tidak, nilai ini ditetapkan kepada objek global atau tidak ditentukan
(2) Cipta komponen persekitaran leksikal
Persekitaran leksikal ialah Struktur data dengan pemetaan pembolehubah-pengecam Pengecam merujuk kepada nama pembolehubah/fungsi, dan pembolehubah adalah rujukan kepada objek sebenar atau data asal.
Terdapat dua komponen di dalam persekitaran leksikal: gaya tebal: perakam persekitaran: digunakan untuk menyimpan lokasi sebenar pembolehubah dan pengisytiharan fungsi rujukan persekitaran luaran: boleh diakses kepada skop induk
(3) Cipta komponen persekitaran pembolehubah
Persekitaran pembolehubah juga merupakan persekitaran leksikal, dan perakam persekitarannya memegang perhubungan mengikat yang dicipta oleh pernyataan perisytiharan pembolehubah dalam konteks pelaksanaan.
Fasa pelaksanaan
Dalam fasa ini, penetapan pembolehubah dan pelaksanaan kod dilakukan
Jika enjin Javascript tidak dapat mencari nilai pembolehubah di lokasi sebenar yang diisytiharkan dalam sumber kod, maka ia akan Berikan nilai yang tidak ditentukan kepadanya
Fasa kitar semula
Letakkan konteks pelaksanaan daripada timbunan dan tunggu mesin maya mengitar semula konteks pelaksanaan
2.9 Bercakap tentang pemahaman anda tentang skop
Skop boleh dilihat sebagai satu set peraturan yang mengawal cara enjin melakukan carian berubah-ubah berdasarkan nama pengecam dalam skop semasa dan subskop bersarang.
Ringkasnya, skop ialah julat yang sah bagi pembolehubah. Data pembolehubah boleh dibaca dan ditulis dalam ruang tertentu, dan ruang ini adalah skop pembolehubah.
(1) Skop global
Kod JS yang ditulis terus dalam teg skrip adalah dalam skop global. Pembolehubah yang diisytiharkan dalam skop global dipanggil pembolehubah global (pembolehubah ditakrifkan di luar tahap blok).
Pembolehubah global boleh digunakan di mana-mana sahaja di dunia;
Skop global dicipta apabila halaman dibuka dan dimusnahkan apabila halaman ditutup.
Semua sifat objek tetingkap mempunyai skop global
Pembolehubah global dan fungsi yang diisytiharkan oleh perintah var dan fungsi ialah sifat dan kaedah objek tetingkap
biar perintah, arahan const, Pembolehubah global yang diisytiharkan oleh arahan kelas bukanlah atribut objek tetingkap
(2) Skop fungsi (skop tempatan)
Skop fungsi dicipta apabila fungsi dipanggil , selepas fungsi itu dilaksanakan, skop dimusnahkan. Setiap kali fungsi dipanggil, skop fungsi baharu dicipta dan ia bebas antara satu sama lain.
Pembolehubah global boleh diakses dalam skop fungsi, tetapi pembolehubah dalam fungsi tidak boleh diakses di luar fungsi.
Apabila mengendalikan pembolehubah dalam skop fungsi, ia akan terlebih dahulu mencari dalam skopnya sendiri Jika ada, ia akan digunakan secara langsung Jika tidak, ia akan mencari dalam skop sebelumnya sehingga ia menemui global Jika skop global ditemui, ia akan digunakan secara langsung Jika masih tidak ditemui dalam skop, ralat akan dilaporkan.
(3) Skop peringkat blok
Sebelum ES6, JavaScript menggunakan skop fungsi dan skop leksikal, dan ES6 memperkenalkan skop peringkat blok.
Sebarang set pernyataan yang dilampirkan dalam sepasang kurungan kerinting {} tergolong dalam pembolehubah yang diisytiharkan menggunakan let dan const dalam blok tidak boleh diakses dari luar peraturan skop ini.
Pembolehubah yang diisytiharkan melalui var atau pengisytiharan fungsi yang dibuat dalam mod tidak ketat tidak mempunyai skop peringkat blok.
(4) Skop leksikal
Skop leksikal ialah skop statik, tidak kira di mana fungsi itu dipanggil, dan tidak kira bagaimana ia dipanggil, skop leksikalnya Skop ditentukan hanya oleh tempat fungsi diisytiharkan.
Fasa analisis leksikal kompilasi pada dasarnya boleh mengetahui di mana dan cara semua pengecam diisytiharkan, supaya ia boleh meramalkan cara mencarinya semasa pelaksanaan.
Dalam erti kata lain, skop leksikal bermakna anda telah memutuskan skop pembolehubah apabila anda menulis kod.
2.10 Apakah itu rantai skop
Apabila menggunakan pembolehubah dalam js, mula-mula enjin js akan cuba menurunkannya dalam skop semasa Cari pembolehubah jika tidak ditemui, cari dalam skop atasnya, dan seterusnya sehingga pembolehubah ditemui atau telah mencapai skop global sedemikian struktur rantaian akses skop pembolehubah dipanggil
Jawapan mendalam
Rantai skop pada asasnya ialah senarai penunjuk kepada objek berubah-ubah. Objek pembolehubah ialah objek yang mengandungi semua pembolehubah dan fungsi dalam persekitaran pelaksanaan. Hujung hadapan rantai skop sentiasa menjadi objek pembolehubah bagi konteks pelaksanaan semasa. Objek berubah bagi konteks pelaksanaan global (iaitu, objek global) sentiasa menjadi objek terakhir dalam rantai skop.
2.11 Peranan rantai skop
Peranan rantai skop adalah untuk memastikan kesahihan semua pembolehubah dan fungsi yang dimiliki oleh persekitaran pelaksanaan akses kepada akses Berjujukan, melalui rantaian skop, boleh mengakses pembolehubah dan fungsi dalam persekitaran luar.
2.12 Senario aplikasi biasa skop
Salah satu senario aplikasi skop biasa ialah modularisasi.
Oleh kerana JavaScript tidak menyokong pemodulatan secara asli, ia telah membawa kepada banyak masalah yang menyelerakan, seperti pencemaran skop global dan konflik nama yang berubah-ubah, struktur kod yang membengkak dan kebolehgunaan semula yang rendah. Sebelum penyelesaian modularisasi formal diperkenalkan, untuk menyelesaikan masalah seperti ini, pembangun berfikir untuk menggunakan skop fungsi untuk mencipta modul.
2.13 Bercakap tentang pra-penghuraian dalam Js?
Apabila enjin JS menjalankan kod, ia akan berfungsi mengikut langkah berikut:
1 Promosikan pengisytiharan pembolehubah ke hadapan skop semasa , hanya pengisytiharan akan dinaikkan pangkat, tetapi tugasan tidak akan dinaikkan pangkat
2 Promosikan pengisytiharan fungsi ke hadapan skop semasa, hanya penyata akan dinaikkan pangkat, tetapi panggilan tidak akan dinaikkan pangkat <.>
3. Promosikan ia fungsi pertama, apabila mempromosikan var2.14 Apakah perbezaan antara promosi berubah dan promosi fungsi?
Promosi boleh ubahRingkasnya, enjin akan pra-kompil sebelum kod JavaScript dilaksanakan Semasa tempoh pra-penyusunan, pengisytiharan pembolehubah dan pengisytiharan fungsi akan dilakukan dinaikkan pangkat kepada peranannya yang sepadan Di bahagian atas skop, pembolehubah yang diisytiharkan dalam fungsi hanya akan dinaikkan ke bahagian atas skop fungsi Apabila pembolehubah ditakrifkan di dalam fungsi adalah sama dengan bahagian luar, pembolehubah dalam badan fungsi akan dinaikkan ke atas. Promosi fungsiPromosi fungsi hanya akan menambah baik penulisan deklaratif fungsi, tiada promosi fungsi dalam penulisan ungkapan fungsi Keutamaan promosi fungsi adalah lebih besar daripada keutamaan pembolehubah promosi , iaitu, pengangkat fungsi adalah di atas pengangkat boleh ubah2.14 Bagaimana untuk memanjangkan rantai skop?
Rantai skop boleh dipanjangkan. Panjangkan rantai skop: Terdapat hanya dua jenis persekitaran pelaksanaan, global dan setempat (fungsi). Walau bagaimanapun, sesetengah kenyataan boleh menambah objek berubah buat sementara waktu di hujung hadapan rantai skop, yang akan dialih keluar selepas kod dilaksanakan. Khususnya, apabila kedua-dua pernyataan ini dilaksanakan, rantai skop akan diperkukuhBlok tangkapan bagi pernyataan cuba-tangkap: objek pembolehubah baharu akan dibuat, mengandungi objek yang dibuang daripada pengisytiharan objek ralat. dengan pernyataan: Pernyataan dengan akan menambah objek yang ditentukan pada rantai skop.2.15 Mekanisme kutipan sampah pelayar
(1) Kitaran hayat memori
Memori yang diperuntukkan dalam persekitaran JS umumnya mempunyai kitaran hayat berikut: Peruntukan memori: Apabila kita mengisytiharkan pembolehubah, fungsi dan objek, sistem akan secara automatik memperuntukkan memori untuk mereka Penggunaan memori: iaitu Baca dan tulis memori, iaitu, gunakan pembolehubah, fungsi, dsb. Kitar semula memori: Selepas digunakan, memori yang tidak digunakan akan dikitar semula secara automatik oleh kutipan sampah Pembolehubah global secara amnya tidak dikitar semula dan pembolehubah tempatan secara amnya Nilai, jika tidak lagi diperlukan, akan dikitar semula secara automatik(2) Konsep pengumpulan sampah
Pengumpulan sampah: Apabila kod JavaScript sedang dijalankan , ruang memori perlu diperuntukkan untuk penyimpanan Pembolehubah dan nilai. Apabila pembolehubah tidak lagi mengambil bahagian dalam operasi, sistem perlu menuntut semula ruang memori yang diduduki Ini adalah pengumpulan sampah. Mekanisme kitar semula: Javascript mempunyai mekanisme pengumpulan sampah automatik, yang akan mengeluarkan memori yang diduduki oleh pembolehubah dan objek yang tidak lagi digunakan digunakan, dan kemudian Lepaskan memori yang didudukinya. Terdapat dua jenis pembolehubah dalam JavaScript: pembolehubah tempatan dan pembolehubah global. Kitaran hayat pembolehubah global akan diteruskan sehingga halaman dipunggah manakala pembolehubah tempatan diisytiharkan dalam fungsi, dan kitaran hayatnya bermula dari pelaksanaan fungsi sehingga akhir pelaksanaan fungsi Semasa proses ini, pembolehubah tempatan akan disimpan nilai mereka dalam timbunan atau timbunan , apabila pelaksanaan fungsi tamat, pembolehubah tempatan ini tidak lagi digunakan, dan ruang yang mereka duduki akan dikeluarkan. Walau bagaimanapun, apabila pembolehubah tempatan digunakan oleh fungsi luaran, salah satu situasi ialah penutupan Selepas pelaksanaan fungsi tamat, pembolehubah di luar fungsi masih menunjuk ke pembolehubah tempatan di dalam fungsi pembolehubah tempatan masih digunakan, jadi tidak dikitar semula.(3) Kaedah kutipan sampah
Ini agak jarang digunakan, algoritma pengiraan rujukan yang digunakan oleh IE. Pengiraan rujukan menjejaki bilangan kali setiap nilai dirujuk. Apabila pembolehubah diisytiharkan dan jenis rujukan diberikan kepada pembolehubah, bilangan rujukan kepada nilai ialah 1. Sebaliknya, jika pembolehubah yang mengandungi rujukan kepada nilai ini memperoleh nilai lain, bilangan rujukan kepada nilai ini dikurangkan dengan satu. Apabila bilangan rujukan menjadi 0, bermakna pembolehubah itu tidak mempunyai nilai Oleh itu, ruang memori yang diduduki oleh pembolehubah ini akan dikeluarkan pada kali berikutnya ia dijalankan semasa tempoh kitar semula mesin.
Kaedah ini akan menyebabkan masalah rujukan bulat: contohnya: obj1 dan obj2 merujuk antara satu sama lain melalui atribut, dan bilangan rujukan kedua-dua objek ialah 2. Apabila menggunakan pengiraan gelung, kerana selepas fungsi dilaksanakan, kedua-dua objek meninggalkan skop dan pelaksanaan fungsi berakhir, obj1 dan obj2 akan terus wujud, jadi bilangan rujukannya tidak akan menjadi 0, yang akan menyebabkan rujukan bulat.
2. Tandakan kaedah pembersihan
Pelayar moden tidak lagi menggunakan algoritma pengiraan rujukan.
Kebanyakan penyemak imbas moden menggunakan beberapa algoritma yang dipertingkatkan berdasarkan algoritma mark-and-clear, dan idea keseluruhan adalah sama.
Pembersihan tanda ialah kaedah pengumpulan sampah biasa dalam penyemak imbas Apabila pembolehubah memasuki persekitaran pelaksanaan, ia ditandakan sebagai "memasuki persekitaran" tidak boleh dikitar semula kerana ia sedang digunakan. Apabila pembolehubah meninggalkan persekitaran, ia akan ditandakan sebagai "meninggalkan persekitaran", dan pembolehubah yang ditandakan sebagai "meninggalkan persekitaran" akan dilepaskan daripada ingatan.
Pengumpul sampah akan menandakan semua pembolehubah yang disimpan dalam ingatan apabila ia dijalankan. Kemudian, ia mengalih keluar pembolehubah dalam persekitaran dan teg yang dirujuk oleh pembolehubah dalam persekitaran. Pembolehubah yang ditandakan selepas ini akan dianggap sebagai pembolehubah yang akan dipadamkan kerana pembolehubah dalam persekitaran tidak lagi boleh mengakses pembolehubah ini. akhirnya. Pengumpul sampah menyelesaikan kerja pembersihan memori, memusnahkan nilai bertanda tersebut dan menuntut semula ruang memori yang mereka duduki.
(4) Bagaimana untuk mengurangkan kutipan sampah
Walaupun pelayar secara automatik boleh mengutip sampah, apabila kodnya lebih kompleks, kos kutipan sampah agak tinggi. , jadi kutipan sampah harus diminimumkan.
Optimumkan tatasusunan: Apabila mengosongkan tatasusunan, cara paling mudah ialah memberikannya nilai [ ], tetapi pada masa yang sama objek kosong baharu akan dicipta dan panjang tatasusunan boleh ditetapkan kepada 0. Ini digunakan untuk mencapai tujuan mengosongkan tatasusunan.
Optimumkan objek: Guna semula objek sebanyak mungkin Untuk objek yang tidak digunakan lagi, tetapkan objek itu kepada null dan kitar semulanya secepat mungkin.
Fungsi Optimumkan: Jika ungkapan fungsi dalam gelung boleh digunakan semula, cuba letakkannya di luar fungsi.
(5) Apakah yang dimaksudkan dengan kebocoran memori
bermakna kerana kecuaian atau ralat, program gagal mengeluarkan memori yang tidak digunakan lagi
(6) Apakah situasi yang akan menyebabkan kebocoran ingatan
Empat situasi berikut akan menyebabkan kebocoran ingatan:
Pembolehubah global yang tidak dijangka: Tidak dijangka kerana penggunaan pembolehubah yang tidak diisytiharkan Pembolehubah global dibuat, meninggalkan pembolehubah ini dalam ingatan dan tidak dapat dikitar semula.
Fungsi pemasa atau panggil balik yang terlupa: Tetapkan pemasa setInterval dan lupa untuk membatalkannya Jika fungsi gelung mempunyai rujukan kepada pembolehubah luaran, maka pembolehubah akan kekal dalam memori dan tidak boleh dikitar semula.
Rujukan daripada DOM: Dapatkan rujukan kepada elemen DOM, dan elemen kemudiannya dipadamkan Memandangkan rujukan kepada elemen ini sentiasa dikekalkan, ia tidak boleh dikitar semula.
Penutupan: Penggunaan penutupan yang tidak betul menyebabkan beberapa pembolehubah kekal dalam ingatan.
3.1 Apakah itu pengaturcaraan berfungsi
Fungsi Pengaturcaraan formal ialah "paradigma pengaturcaraan", metodologi untuk menulis atur cara
Terdapat tiga paradigma pengaturcaraan utama: pengaturcaraan imperatif, pengaturcaraan deklaratif dan pengaturcaraan berfungsi
Berbanding dengan pengaturcaraan imperatif, pengaturcaraan berfungsi lebih menekankan pada hasil pelaksanaan program dan bukannya proses pelaksanaan Ia menyokong penggunaan beberapa unit pelaksanaan mudah untuk membuat hasil pengiraan progresif dan untuk memperoleh operasi yang kompleks lapisan demi lapisan daripada mereka bentuk proses pelaksanaan yang kompleks
<.>3.2 Kelebihan dan Kelemahan Pengaturcaraan Berfungsi
KelebihanPengurusan negeri yang lebih baik: kerana tujuannya adalah untuk menjadi stateless , atau kurang negeri, boleh meminimumkan yang tidak diketahui ini, mengoptimumkan kod dan mengurangkan ralatPenggunaan semula yang lebih mudah: input tetap->output tetap, tiada pengaruh daripada pembolehubah luaran lain dan tiada kesan sampingan. Dengan cara ini, apabila kod digunakan semula, tidak perlu mempertimbangkan pelaksanaan dalamannya dan kesan luaran Kombinasi yang lebih elegan: Secara umum, halaman web terdiri daripada pelbagai komponen. Dalam istilah yang lebih kecil, fungsi juga boleh terdiri daripada beberapa fungsi kecil. Kebolehgunaan semula yang lebih kukuh membawa gabungan yang lebih berkuasa faedah tersembunyi. Kurangkan jumlah kod dan tingkatkan kebolehselenggaraanKeburukan性能:函数式编程相对于指令式编程,性能绝对是一个短板,因为它往往会对一个方法进行过度包装,从而产生上下文切换的性能开销
资源占用:在 JS 中为了实现对象状态的不可变,往往会创建新的对象,因此,它对垃圾回收所产生的压力远远超过其他编程方式
递归陷阱:在函数式编程中,为了实现迭代,通常会采用递归操作
3.3 什么是纯函数,它有什么优点
纯函数是对给定的输入返还相同输出的函数,并且要求你所有的数据都是不可变的,即纯函数=无状态+数据不可变
特性:
函数内部传入指定的值,就会返回确定唯一的值
不会造成超出作用域的变化,例如修改全局变量或引用传递的参数
优势:
使用纯函数,我们可以产生可测试的代码
不依赖外部环境计算,不会产生副作用,提高函数的复用性
可读性更强 ,函数不管是否是纯函数 都会有一个语义化的名称,更便于阅读
可以组装成复杂任务的可能性。符合模块化概念及单一职责原则
3.4 什么是组合函数 (compose)
在函数式编程中,有一个很重要的概念就是函数组合,实际上就是把处理的函数数据像管道一样连接起来,然后让数据穿过管道连接起来,得到最终的结果。
组合函数,其实大致思想就是将 多个函数组合成一个函数,c(b(a(a(1)))) 这种写法简写为 compose(c, b, a, a)(x) 。但是注意这里如果一个函数都没有传入,那就是传入的是什么就返回什么,并且函数的执行顺序是和传入的顺序相反的。
var compose = (...funcs) => { // funcs(数组):记录的是所有的函数 // 这里其实也是利用了柯里化的思想,函数执行,生成一个闭包,预先把一些信息存储,供下级上下文使用 return (x) => { var len = funcs.length; // 如果没有函数执行,直接返回结果 if (len === 0) return x; if (len === 1) funcs[0](x); return funcs.reduceRight((res, func) => { return func(res); }, x); }; }; var resFn = compose(c, b, a, a); resFn(1);
组合函数的思想,在很多框架中也被使用,例如:redux,实现效果来说是其实和上面的代码等价。
3.5 什么是惰性函数
惰性载入表示函数执行的分支只会在函数第一次掉用的时候执行,在第一次调用过程中,该函数会被覆盖为另一个按照合适方式执行的函数,这样任何对原函数的调用就不用再经过执行的分支了
惰性函数相当于有记忆的功能一样,当它已经判断了一遍的话,第二遍就不会再判断了。
比如现在要求写一个test函数,这个函数返回首次调用时的new Date().getTime(),注意是首次,而且不允许有全局变量的污染
//一般会这样实现 var test = (function () { var t = null; return function () { if (t) { return t; } t = new Date().getTime(); return t; } })(); // 用惰性函数实现 var test = function () { var t = new Date().getTime(); test = function () { return t; } return test(); } console.log(test()); console.log(test()); console.log(test());
3.6 什么是高阶函数
高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。
3.7 说说你对函数柯里化的理解
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
函数柯里化的好处:
(1)参数复用:需要输入多个参数,最终只需输入一个,其余通过 arguments 来获取
(2)提前确认:避免重复去判断某一条件是否符合,不符合则 return 不再继续执行下面的操作
(3)延迟运行:避免重复的去执行程序,等真正需要结果的时候再执行
3.8 什么是箭头函数,有什么特征
使用 "箭头" ( => ) 来定义函数. 箭头函数相当于匿名函数, 并且简化了函数定义
箭头函数的特征:
箭头函数没有this, this指向定义箭头函数所处的外部环境
箭头函数的this永远不会变,call、apply、bind也无法改变
箭头函数只能声明成匿名函数,但可以通过表达式的方式让箭头函数具名
箭头函数没有原型prototype
箭头函数不能当做一个构造函数 因为 this 的指向问题
箭头函数没有 arguments 在箭头函数内部访问这个变量访问的是外部环境的arguments, 可以使用 ...代替
3.9 说说你对递归函数的理解
如果一个函数在内部调用自身本身,这个函数就是递归函数
其核心思想是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
一般来说,递归需要有边界条件、递归前进阶段和递归返回阶段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回
优点:结构清晰、可读性强
缺点:效率低、调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。
3.10 什么是尾递归
尾递归,即在函数尾位置调用自身(或是一个尾调用本身的其他函数等等)。
在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储,递归次数过多容易造成栈溢出
这时候,我们就可以使用尾递归,即一个函数中所有递归形式的调用都出现在函数的末尾,对于尾递归来说,由于只存在一个调用记录,所以永远不会发生"栈溢出"错误
3.11 函数传参,传递复杂数据类型和简单数据类型有什么区别
传递复杂数据类型传递的是引用的地址,修改会改变
简单数据类型传递的是具体的值,不会相互影响
/* let a = 8 function fn(a) { a = 9 } fn(a) console.log(a) // 8 */ let a = { age: 8 } function fn(a) { a.age = 9 } fn(a) console.log(a.age) // 9
3.12 函数声明与函数表达式的区别
函数声明: funtion开头,有函数提升
函数表达式: 不是funtion开头,没有函数提升
3.13 什么是函数缓存,如何实现?
概念
函数缓存,就是将函数运算过的结果进行缓存
本质上就是用空间(缓存存储)换时间(计算过程)
常用于缓存数据计算结果和缓存对象
如何实现
实现函数缓存主要依靠闭包、柯里化、高阶函数
应用场景
对于昂贵的函数调用,执行复杂计算的函数
对于具有有限且高度重复输入范围的函数
对于具有重复输入值的递归函数
对于纯函数,即每次使用特定输入调用时返回相同输出的函数
3.14 call、apply、bind三者的异同
共同点 :
都可以改变this指向;
三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window
不同点:
call 和 apply 会调用函数, 并且改变函数内部this指向.
call 和 apply传递的参数不一样,call传递参数使用逗号隔开,apply使用数组传递,且apply和call是一次性传入参数,而bind可以分为多次传入
bind是返回绑定this之后的函数
应用场景
call 经常做继承.
apply经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指
【相关推荐:JavaScript视频教程、web前端】
Atas ialah kandungan terperinci Ringkasan temuduga 10,000 perkataan JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!