C語言中,函數指針是指向函數的指針變量。它通常被用于在運行時動態地調用不同的函數。在JavaScript中,沒有直接的概念來理解C語言的函數指針,因為JavaScript的運行機制與C語言有很大的不同。
然而,我們可以嘗試通過一些類比來理解函數指針的概念。
在JavaScript中,函數是一等公民,可以作為參數傳遞給其他函數,也可以作為返回值。與C語言不同的是,JavaScript沒有直接提供函數指針的概念。但是,我們可以通過將函數作為對象屬性或使用箭頭函數的特性來模擬函數指針的一些行為。
下面是一個示例,演示如何使用JavaScript模擬C語言中的函數指針:
```javascript
// 定義一個對象,用于存儲要調用的函數
const funcPointer = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
// 定義一個函數,該函數接受一個對象和要執行的函數名
function executeFunction(obj, functionName) {
// 通過對象屬性訪問指定的函數,并執行它
return obj[functionName](10, 20);
}
// 使用示例
console.log(executeFunction(funcPointer, 'add')); // 輸出 30
console.log(executeFunction(funcPointer, 'subtract')); // 輸出 -10
```
在上面的示例中,我們通過對象`funcPointer`來存儲要調用的兩個函數。然后,我們定義了一個函數`executeFunction`,它接受一個對象和一個函數名作為參數。在`executeFunction`中,我們通過對象屬性訪問指定的函數,并執行它。這樣,我們就可以根據需要動態地調用不同的函數。
雖然這個示例不能完全等同于C語言中的函數指針,但它提供了一種類似的行為。通過使用對象屬性和箭頭函數,我們可以在JavaScript中模擬函數指針的概念。
#如何自學C++#
TML全局屬性是所有HTML元素共有的屬性。它們可以應用于所有元素,盡管它們可能對某些元素沒有影響。
HTML元素可以設置屬性
屬性可以在元素中添加附加信息
屬性一般描述于開始標簽
屬性總是以名稱/值對的形式出現,比如:name="value"。
屬性和屬性值對大小寫不敏感。不過,萬維網聯盟在其HTML4推薦標準中推薦小寫的屬性/屬性值。而新版本的(X)HTML要求使用小寫屬性。
class:為html元素定義一個或多個類名(classname)(類名從樣式文件引入)
id:定義元素的唯一id
style:規定元素的行內樣式(inlinestyle)
title:描述了元素的額外信息(作為工具條使用)
HTML使用標簽<a>來設置超文本鏈接。超鏈接可以是一個字,一個詞,或者一組詞,也可以是一幅圖像,您可以點擊這些內容來跳轉到新的文檔或者當前文檔中的某個部分。當您把鼠標指針移動到網頁中的某個鏈接上時,箭頭會變為一只小手。默認情況下,鏈接將以以下形式出現在瀏覽器中:
一個未訪問過的鏈接顯示為藍色字體并帶有下劃線。
訪問過的鏈接顯示為紫色并帶有下劃線。
點擊鏈接時,鏈接顯示為紅色并帶有下劃線。
如果為這些超鏈接設置了CSS樣式,展示樣式會根據CSS的設定而顯示。
在標簽<a>中使用了href屬性來描述鏈接的地址。
實例
<a href="https://www.kaikeba.com/">訪問開課吧</a>1復制代碼類型:[html]
上面這行代碼顯示為:訪問開課吧
點擊這個超鏈接會把用戶帶到開課吧的首頁。
使用target屬性,你可以定義被鏈接的文檔在何處顯示。
實例
<ahref="https://www.kaikeba.com/"target="_blank">訪問開課吧</a>
target="_blank":在新窗口中打開被鏈接文檔。
target="_self": 默認,在相同的框架中打開被鏈接文檔。
target="_parent":在父框架集中打開被鏈接文檔。
target="_top": 在整個窗口中打開被鏈接文檔。
target=framename:在指定的框架中打開被鏈接文檔。 1234567891011復制代碼類型:[html]
HTML圖像標簽及其屬性
在HTML中,圖像由<img>標簽定義。<img>是空標簽,意思是說,它只包含屬性,并且沒有閉合標簽。
要在頁面上顯示圖像,你需要使用源屬性(src)。src指"source"。源屬性的值是圖像的URL地址。
定義圖像的語法是:
<imgsrc="url"alt="some_text"> 1復制代碼類型:[html]
URL指存儲圖像的位置。
alt屬性用來為圖像定義一串預備的可替換的文本。在瀏覽器無法載入圖像時,替換文本屬性告訴讀者她們失去的信息。此時,瀏覽器將顯示這個替代性的文本而不是圖像。為頁面上的圖像都加上替換文本屬性是個好習慣,這樣有助于更好的顯示信息,并且對于那些使用純文本瀏覽器的人來說是非常有用的。
height(高度)與width(寬度)屬性用于設置圖像的高度與寬度。屬性值默認單位為像素。
<imgsrc="logo.jpg"alt="kaikeba"width="300"height="120"> 1復制代碼類型:[html]
提示:指定圖像的高度和寬度是一個很好的習慣。如果圖像指定了高度寬度,頁面加載時就會保留指定的尺寸。如果沒有指定圖片的大小,加載頁面時有可能會破壞HTML頁面的整體布局。
開課吧廣場-人才學習交流平臺
JavaScirpt 使用 Number 類型來表示數字(整數或浮點數),遵循 IEEE 754 標準,通過 64 位來表示一個數字(1 + 11 + 52)
最大安全數字:Number.MAX_SAFE_INTEGER = Math.pow(2, 53) - 1,轉換成整數就是 16 位,所以 0.1 === 0.1,是因為通過 toPrecision(16) 去有效位之后,兩者是相等的。
在兩數相加時,會先轉換成二進制,0.1 和 0.2 轉換成二進制的時候尾數會發生無限循環,然后進行對階運算,JS 引擎對二進制進行截斷,所以造成精度丟失。
所以總結:精度丟失可能出現在進制轉換和對階運算中
基本類型:Number、Boolean、String、null、undefined、symbol(ES6 新增的),BigInt(ES2020) 引用類型:Object,對象子類型(Array,Function)
Math.pow(2, 53) ,53 為有效數字,會發生截斷,等于 JS 能支持的最大數字。
淺克隆:
function shallowClone(obj) {
let cloneObj = {};
for (let i in obj) {
cloneObj[i] = obj[i];
}
return cloneObj;
}
復制代碼
深克隆:
function deepCopy(obj) {
if (typeof obj === 'object') {
var result = obj.constructor === Array ? [] : {};
for (var i in obj) {
result[i] = typeof obj[i] === 'object' ? deepCopy(obj[i]) : obj[i];
}
} else {
var result = obj;
}
return result;
}
復制代碼
事件流是網頁元素接收事件的順序,"DOM2級事件"規定的事件流包括三個階段:事件捕獲階段、處于目標階段、事件冒泡階段。 首先發生的事件捕獲,為截獲事件提供機會。然后是實際的目標接受事件。最后一個階段是時間冒泡階段,可以在這個階段對事件做出響應。 雖然捕獲階段在規范中規定不允許響應事件,但是實際上還是會執行,所以有兩次機會獲取到目標對象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡</title>
</head>
<body>
<div>
<p id="parEle">我是父元素 <span id="sonEle">我是子元素</span></p>
</div>
</body>
</html>
<script type="text/javascript">
var sonEle = document.getElementById('sonEle');
var parEle = document.getElementById('parEle');
parEle.addEventListener('click', function () {
alert('父級 冒泡');
}, false);
parEle.addEventListener('click', function () {
alert('父級 捕獲');
}, true);
sonEle.addEventListener('click', function () {
alert('子級冒泡');
}, false);
sonEle.addEventListener('click', function () {
alert('子級捕獲');
}, true);
</script>
復制代碼
當容器元素及嵌套元素,即在捕獲階段又在冒泡階段調用事件處理程序時:事件按DOM事件流的順序執行事件處理程序:
且當事件處于目標階段時,事件調用順序決定于綁定事件的書寫順序,按上面的例子為,先調用冒泡階段的事件處理程序,再調用捕獲階段的事件處理程序。依次alert出“子集冒泡”,“子集捕獲”。
基于發布訂閱模式,就是在瀏覽器加載的時候會讀取事件相關的代碼,但是只有實際等到具體的事件觸發的時候才會執行。
比如點擊按鈕,這是個事件(Event),而負責處理事件的代碼段通常被稱為事件處理程序(Event Handler),也就是「啟動對話框的顯示」這個動作。
在 Web 端,我們常見的就是 DOM 事件:
構造調用:
如果函數返回一個對象,那么new 這個函數調用返回這個函數的返回對象,否則返回 new 創建的新對象
可以用來表示一個獨一無二的變量防止命名沖突。但是面試官問還有嗎?我沒想出其他的用處就直接答我不知道了,還可以利用 symbol 不會被常規的方法(除了 Object.getOwnPropertySymbols 外)遍歷到,所以可以用來模擬私有變量。
主要用來提供遍歷接口,布置了 symbol.iterator 的對象才可以使用 for···of 循環,可以統一處理數據結構。調用之后回返回一個遍歷器對象,包含有一個 next 方法,使用 next 方法后有兩個返回值 value 和 done 分別表示函數當前執行位置的值和是否遍歷完畢。
Symbol.for() 可以在全局訪問 symbol
閉包是指有權訪問另外一個函數作用域中的變量的函數
JavaScript代碼的整個執行過程,分為兩個階段,代碼編譯階段與代碼執行階段。編譯階段由編譯器完成,將代碼翻譯成可執行代碼,這個階段作用域規則會確定。執行階段由引擎完成,主要任務是執行可執行代碼,執行上下文在這個階段創建。
ES5 中只存在兩種作用域:全局作用域和函數作用域。在 JavaScript 中,我們將作用域定義為一套規則,這套規則用來管理引擎如何在當前作用域以及嵌套子作用域中根據標識符名稱進行變量(變量名或者函數名)查找
首先要了解作用域鏈,當訪問一個變量時,編譯器在執行這段代碼時,會首先從當前的作用域中查找是否有這個標識符,如果沒有找到,就會去父作用域查找,如果父作用域還沒找到繼續向上查找,直到全局作用域為止,,而作用域鏈,就是有當前作用域與上層作用域的一系列變量對象組成,它保證了當前執行的作用域對符合訪問權限的變量和函數的有序訪問。
當前環境中存在指向父級作用域的引用
閉包是一種特殊的對象,它由兩部分組成:執行上下文(代號 A),以及在該執行上下文中創建的函數 (代號 B),當 B 執行時,如果訪問了 A 中變量對象的值,那么閉包就會產生,且在 Chrome 中使用這個執行上下文 A 的函數名代指閉包。
Not a Number,表示非數字,typeof NaN === 'number'
一般非基礎類型進行轉換時會先調用 valueOf,如果 valueOf 無法返回基本類型值,就會調用 toString
[] + {} 和 {} + []
復制代碼
寬松相等允許進行強制類型轉換,而嚴格相等不允許
轉換為數字然后比較
它們都是函數的方法
call: Array.prototype.call(this, args1, args2]) apply: Array.prototype.apply(this, [args1, args2]) :ES6 之前用來展開數組調用, foo.appy(null, []),ES6 之后使用 ... 操作符
四條規則:
function foo() {
console.log(this.a);
}
var a = 2;
foo();
復制代碼
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo,
}
obj.foo(); // 2
復制代碼
function foo() {
console.log(this.a);
}
var obj = {
a: 2
};
foo.call(obj);
復制代碼
顯示綁定之硬綁定
function foo(something) {
console.log(this.a, something);
return this.a + something;
}
function bind(fn, obj) {
return function() {
return fn.apply(obj, arguments);
};
}
var obj = {
a: 2
}
var bar = bind(foo, obj);
復制代碼
New 綁定,new 調用函數會創建一個全新的對象,并將這個對象綁定到函數調用的 this。
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log(bar.a)
復制代碼
// call
Function.prototype.call = function (context, ...args) {
context = context || window;
const fnSymbol = Symbol("fn");
context[fnSymbol] = this;
context[fnSymbol](...args);
delete context[fnSymbol];
}
復制代碼
// apply
Function.prototype.apply = function (context, argsArr) {
context = context || window;
const fnSymbol = Symbol("fn");
context[fnSymbol] = this;
context[fnSymbol](...argsArr);
delete context[fnSymbol];
}
復制代碼
// bind
Function.prototype.bind = function (context, ...args) {
context = context || window;
const fnSymbol = Symbol("fn");
context[fnSymbol] = this;
return function (..._args) {
args = args.concat(_args);
context[fnSymbol](...args);
delete context[fnSymbol];
}
}
復制代碼
setTimeout 按照順序放到隊列里面,然后等待函數調用棧清空之后才開始執行,而這些操作進入隊列的順序,則由設定的延遲時間來決定
class MyPromise {
constructor(fn) {
this.resolvedCallbacks = [];
this.rejectedCallbacks = [];
this.state = 'PENDING';
this.value = '';
fn(this.resolve.bind(this), this.reject.bind(this));
}
resolve(value) {
if (this.state === 'PENDING') {
this.state = 'RESOLVED';
this.value = value;
this.resolvedCallbacks.map(cb => cb(value));
}
}
reject(value) {
if (this.state === 'PENDING') {
this.state = 'REJECTED';
this.value = value;
this.rejectedCallbacks.map(cb => cb(value));
}
}
then(onFulfilled, onRejected) {
if (this.state === 'PENDING') {
this.resolvedCallbacks.push(onFulfilled);
this.rejectedCallbacks.push(onRejected);
}
if (this.state === 'RESOLVED') {
onFulfilled(this.value);
}
if (this.state === 'REJECTED') {
onRejected(this.value);
}
}
}
復制代碼
Object.keys(obj).length === 0
手寫題:在線編程,getUrlParams(url,key); 就是很簡單的獲取url的某個參數的問題,但要考慮邊界情況,多個返回值等等
onload 是所以加載完成之后執行的
onclick 和 addEventListener
冒泡和捕獲
function Person(name) {
this.name = name;
}
Person.prototype.constructor = Person
復制代碼
什么是原型鏈?
當對象查找一個屬性的時候,如果沒有在自身找到,那么就會查找自身的原型,如果原型還沒有找到,那么會繼續查找原型的原型,直到找到 Object.prototype 的原型時,此時原型為 null,查找停止。 這種通過 通過原型鏈接的逐級向上的查找鏈被稱為原型鏈
什么是原型繼承?
一個對象可以使用另外一個對象的屬性或者方法,就稱之為繼承。具體是通過將這個對象的原型設置為另外一個對象,這樣根據原型鏈的規則,如果查找一個對象屬性且在自身不存在時,就會查找另外一個對象,相當于一個對象可以使用另外一個對象的屬性和方法了。
是基于原型的動態語言,主要獨特特性有 this、原型和原型鏈。
JS 嚴格意義上來說分為:語言標準部分(ECMAScript)+ 宿主環境部分
2015 年發布 ES6,引入諸多新特性使得能夠編寫大型項目變成可能,標準自 2015 之后以年號代號,每年一更
Array.isArray
是類數組,是屬于鴨子類型的范疇,長得像數組,
為 JS 添加類型支持,以及提供最新版的 ES 語法的支持,是的利于團隊協作和排錯,開發大型項目
漸進式網絡應用(PWA)是谷歌在2015年底提出的概念。基本上算是web應用程序,但在外觀和感覺上與原生app類似。支持PWA的網站可以提供脫機工作、推送通知和設備硬件訪問等功能。
Service Worker是瀏覽器在后臺獨立于網頁運行的腳本,它打開了通向不需要網頁或用戶交互的功能的大門。 現在,它們已包括如推送通知和后臺同步等功能。 將來,Service Worker將會支持如定期同步或地理圍欄等其他功能。 本教程討論的核心功能是攔截和處理網絡請求,包括通過程序來管理緩存中的響應。
Object.create() 會創建一個 “新” 對象,然后將此對象內部的 [[Prototype]] 關聯到你指定的對象(Foo.prototype)。Object.create(null) 創建一個空 [[Prototype]] 鏈接的對象,這個對象無法進行委托。
function Foo(name) {
this.name = name;
}
Foo.prototype.myName = function () {
return this.name;
}
// 繼承屬性,通過借用構造函數調用
function Bar(name, label) {
Foo.call(this, name);
this.label = label;
}
// 繼承方法,創建備份
Bar.prototype = Object.create(Foo.prototype);
// 必須設置回正確的構造函數,要不然在會發生判斷類型出錯
Bar.prototype.constructor = Bar;
// 必須在上一步之后
Bar.prototype.myLabel = function () {
return this.label;
}
var a = new Bar("a", "obj a");
a.myName(); // "a"
a.myLabel(); // "obj a"
復制代碼
不會繼承,因為根據 this 綁定四大規則,new 綁定的優先級高于 bind 顯示綁定,通過 new 進行構造函數調用時,會創建一個新對象,這個新對象會代替 bind 的對象綁定,作為此函數的 this,并且在此函數沒有返回對象的情況下,返回這個新建的對象
function foo() {
return (a) => {
console.log(this.a);
}
}
var obj1 = {
a: 2
}
var obj2 = {
a: 3
}
var bar = foo.call(obj1);
bar.call(obj2);
復制代碼
為這個類的函數對象直接添加方法,而不是加在這個函數對象的原型對象上
事件循環機制從整體上告訴了我們 JavaScript 代碼的執行順序 Event Loop即事件循環,是指瀏覽器或Node的一種解決javaScript單線程運行時不會阻塞的一種機制,也就是我們經常使用異步的原理。
先執行宏任務隊列,然后執行微任務隊列,然后開始下一輪事件循環,繼續先執行宏任務隊列,再執行微任務隊列。
上訴的 setTimeout 和 setInterval 等都是任務源,真正進入任務隊列的是他們分發的任務。
for (const macroTask of macroTaskQueue) {
handleMacroTask();
for (const microTask of microTaskQueue) {
handleMicroTask(microTask);
}
}
復制代碼
function flatten(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]));
} else {
result = result.concat(arr[i]);
}
}
return result;
}
const a = [1, [2, [3, 4]]];
console.log(flatten(a));
復制代碼
預先設置一些參數
柯里化是什么:是指這樣一個函數,它接收函數 A,并且能返回一個新的函數,這個新的函數能夠處理函數 A 的剩余參數
function createCurry(func, args) {
var argity = func.length;
var args = args || [];
return function () {
var _args = [].slice.apply(arguments);
args.push(..._args);
if (args.length < argity) {
return createCurry.call(this, func, args);
}
return func.apply(this, args);
}
}
復制代碼
Array.from(new Set([1, 1, 2, 2]))
復制代碼
let 會產生臨時性死區,在當前的執行上下文中,會進行變量提升,但是未被初始化,所以在執行上下文執行階段,執行代碼如果還沒有執行到變量賦值,就引用此變量就會報錯,此變量未初始化。
函數在運行的時候,會首先創建執行上下文,然后將執行上下文入棧,然后當此執行上下文處于棧頂時,開始運行執行上下文。
在創建執行上下文的過程中會做三件事:創建變量對象,創建作用域鏈,確定 this 指向,其中創建變量對象的過程中,首先會為 arguments 創建一個屬性,值為 arguments,然后會掃碼 function 函數聲明,創建一個同名屬性,值為函數的引用,接著會掃碼 var 變量聲明,創建一個同名屬性,值為 undefined,這就是變量提升 ** **問:**如何看待 PWA App、原生 App 以及 Flutter 和 React Native 這種前端驅動的開發模式?
左邊可以是任意值,右邊只能是函數
*請認真填寫需求信息,我們會在24小時內與您取得聯系。