目錄
第一個問:安全性類型偵測-typeof和instanceof 差異以及缺陷,以及解決方案
第三問:作用域安全的建構子--當我們new一個建構子的時候可以得到一個實例,要是我們忘記寫new了呢?
第四問:談談惰性載入函數
第五问:谈一下函数节流
第六问:谈一下函数防抖
第七问:谈一下requestAnimationFrame
第八问:web计时,你知道该怎么计算首屏,白屏时间吗?
第九问:你知道web Worker吗?
work.js
首頁 web前端 js教程 【進階技巧】九個前端面試題,帶你鞏固知識點!

【進階技巧】九個前端面試題,帶你鞏固知識點!

Oct 18, 2022 pm 08:33 PM
javascript web前端 前端

這篇文章分享前端進階技巧,整理總結九個前端面試題,帶你鞏固知識點,希望對大家有幫助!

【進階技巧】九個前端面試題,帶你鞏固知識點!

第一個問:安全性類型偵測-typeof和instanceof 差異以及缺陷,以及解決方案

##這兩個方法都可以用來判斷變數類型

區別:前者是判斷這個變數是什麼類型,後者是判斷這個變數是不是某種類型,傳回的是布林值

(1)typeof

缺陷:

1.無法判斷變數具體的資料型態例如陣列、正規、日期、對象,因為都會傳回object,不過可以判斷function,如果偵測物件是正規表示式的時候,在Safari和Chrome中使用typeof的時候會錯誤的返回"function",其他的瀏覽器返回的是object.

#2.判斷null的時候回傳的是一個object,這是js的一個缺陷,判斷NaN的時候回傳是number

(2)instanceof 可以用來偵測這個變數是否為某種類型,傳回的是布林值,並且可以判斷這個變數是否為某個函數的實例,它檢測的是對象的原型

let num = 1
num instanceof Number // false


num = new Number(1)
num instanceof Number // true
登入後複製

明明都是num,而且都是1,只是因為第一個不是對象,是基本類型,所以直接回傳false,而第二個是封裝成對象,所以true。

這裡要嚴格注意這個問題,有些說法是偵測目標的__proto__與建構子的prototype相同即回傳true,這是不嚴謹的,偵測的一定要是物件才行,如:

let num = 1
num.__proto__ === Number.prototype // true
num instanceof Number // false

num = new Number(1)
num.proto === Number.prototype // true
num instanceof Number // true

num.proto === (new Number(1)).proto // true
登入後複製

此外,instanceof還有另一個缺點:如果一個頁面上有多個框架,即有多個全局環境,那麼我在a框架裡定義一個Array,然後在b框架裡去用instanceof去判斷,那麼該array的原型鏈上不可能找到b框架裡的array,則會判斷該array不是一個array。

解決方案:使用Object.prototype.toString.call(value) 方法去呼叫對象,得到對象的建構函式名稱。可以解決instanceof的跨框架問題,缺點是對使用者自訂的類型,它只會返回[object Object]

第二問:既然提到了instanceof,那麼手寫實作下instanceof吧
// [1,2,3] instanceof Array ---- true

// L instanceof R
// 变量R的原型 存在于 变量L的原型链上
function instance_of(L,R){    
    // 验证如果为基本数据类型,就直接返回false
    const baseType = ['string', 'number','boolean','undefined','symbol']
    if(baseType.includes(typeof(L))) { return false }
    
    let RP  = R.prototype;  //取 R 的显示原型
    L = L.__proto__;       //取 L 的隐式原型
    while(true){           // 无线循环的写法(也可以使 for(;;) )
        if(L === null){    //找到最顶层
            return false;
        }
        if(L === RP){       //严格相等
            return true;
        }
        L = L.__proto__;  //没找到继续向上一层原型链查找
    }
}
登入後複製

第三問:作用域安全的建構子--當我們new一個建構子的時候可以得到一個實例,要是我們忘記寫new了呢?

例如

function Person(){
    this.name = "小红"
}


p = Person();
登入後複製

這會發生什麼問題? ,怎麼解決

這樣直接使用,this會對應到全域物件window上。解決方法可以是:先確認this物件是正確類型的實例。如果不是,那麼會建立新的實例並傳回。請看下面的範例

function Person(){
    if(this instanceof Person){
        this.name = "小红"
    }else{
        return  new Person()
    }
}


p = Person();
登入後複製

第四問:談談惰性載入函數

在JavaScript程式碼中,由於瀏覽器之間行為的差異,多數JavaScript程式碼包含了大量的if語句,以檢查瀏覽器特性,解決不同瀏覽器的相容問題。例如新增事件的函數:

function addEvent (element, type, handler) {
    if (element.addEventListener) {
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + type, handler);
    } else {
        element["on" + type] = handler;
    }
}
登入後複製

每次呼叫addEvent()的時候,都要對瀏覽器所支援的能力仔細檢查。首先檢查是否支援addEventListener方法,如果不支援再檢查是否支援attachEvent方法,如果還不支持,就用DOM 0級的方法加入事件。在呼叫addEvent()過程中,每次這個過程都要走一遍。其實,瀏覽器支援其中的一種方法就會一直支援他,就沒有必要再進行其他分支的偵測了,也就是說if語句不必每次都執行,程式碼可以運行的更快一些。解決的方案稱之為惰性載入。所謂惰性載入,就是說函數的if分支只會執行一次,之後呼叫函數時,直接進入所支援的分支程式碼。有兩種實現惰性載入的方式,第一種事函數在第一次呼叫時,對函數本身進行二次處理,該函數會被覆寫為符合分支條件的函數,這樣對原函數的呼叫就不用再經過執行的分支了,我們可以用下面的方式使用惰性載入重寫addEvent()。

function addEvent (type, element, handler) {
    if (element.addEventListener) {
        addEvent = function (type, element, handler) {
            element.addEventListener(type, handler, false);
        }
    }
    else if(element.attachEvent){
        addEvent = function (type, element, handler) {
            element.attachEvent('on' + type, handler);
        }
    }
    else{
        addEvent = function (type, element, handler) {
            element['on' + type] = handler;
        }
    }
    return addEvent(type, element, handler);
}
登入後複製

在這個惰性載入的addEvent()中,if語句的每個分支都會為addEvent變數賦值,有效覆寫了原函數。最後一步便是呼叫了新賦函數。下次呼叫addEvent()的時候,就會直接呼叫新賦值的函數,這樣就不用再執行if語句了。

第二種實作惰性載入的方式是在宣告函數時就指定適當的函數。這樣在第一次呼叫函數時就不會損失效能了,只在程式碼載入時會損失一點效能。一下就是按照這一思路重寫的addEvent()。

var addEvent = (function () {
    if (document.addEventListener) {
        return function (type, element, fun) {
            element.addEventListener(type, fun, false);
        }
    }
    else if (document.attachEvent) {
        return function (type, element, fun) {
            element.attachEvent('on' + type, fun);
        }
    }
    else {
        return function (type, element, fun) {
            element['on' + type] = fun;
        }
    }
})();
登入後複製

這個例子中使用的技巧是創建一個匿名的自執行函數,透過不同的分支以確定應該使用那個函數實現,實際的邏輯都一樣,不一樣的地方就是使用了函數表達式(使用了var定義函數)和新增了一個匿名函數,另外每個分支都傳回一個正確的函數,並立即將其賦值給變數addEvent。

惰性载入函数的优点只执行一次if分支,避免了函数每次执行时候都要执行if分支和不必要的代码,因此提升了代码性能,至于那种方式更合适,就要看您的需求而定了。

第五问:谈一下函数节流

概念:限制一个函数在一定时间内只能执行一次。

主要实现思路 就是通过 setTimeout 定时器,通过设置延时时间,在第一次调用时,创建定时器,先设定一个变量true,写入需要执行的函数。第二次执行这个函数时,会判断变量是否true,是则返回。当第一次的定时器执行完函数最后会设定变量为false。那么下次判断变量时则为false,函数会依次运行。目的在于在一定的时间内,保证多次函数的请求只执行最后一次调用。

函数节流的代码实现

function throttle(fn,wait){
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                fn.apply(context,args);
                timer = null;
            },wait)
        }
    }
}


function handle(){
console.log(Math.random());
}

window.addEventListener("mousemove",throttle(handle,1000));
登入後複製

函数节流的应用场景(throttle)

  • DOM 元素的拖拽功能实现(mousemove)
  • 高频点击提交,表单重复提交
  • 搜索联想(keyup)
  • 计算鼠标移动的距离(mousemove)
  • 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
  • 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,- - 才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次.

第六问:谈一下函数防抖

概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。

函数防抖的要点,是需要一个 setTimeout 来辅助实现,延迟运行需要执行的代码。如果方法多次触发,则把上次记录的延迟执行代码用 clearTimeout 清掉,重新开始计时。若计时期间事件没有被重新触发,等延迟时间计时完毕,则执行目标代码。

函数防抖的代码实现

function debounce(fn,wait){
    var timer = null;
    return function(){
        if(timer !== null){
            clearTimeout(timer);
        }
        timer = setTimeout(fn,wait);
    }
}
    
function handle(){
    console.log(Math.random());
}
    
window.addEventListener("resize",debounce(handle,1000));
登入後複製

函数防抖的使用场景 函数防抖一般用在什么情况之下呢?一般用在,连续的事件只需触发一次回调的场合。具体有:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求;
  • 用户名、手机号、邮箱输入验证;
  • 浏览器窗口大小改变后,只需窗口调整完后,再执行 resize 事件中的代码,防止重复渲染。

目前遇到过的用处就是这些,理解了原理与实现思路,小伙伴可以把它运用在任何需要的场合,提高代码质量。

第七问:谈一下requestAnimationFrame

动画原理 : 眼前所看到图像正在以每秒60次的频率刷新,由于刷新频率很高,因此你感觉不到它在刷新。而动画本质就是要让人眼看到图像被刷新而引起变化的视觉效果,这个变化要以连贯的、平滑的方式进行过渡。 那怎么样才能做到这种效果呢?

刷新频率为60Hz的屏幕每16.7ms刷新一次,我们在屏幕每次刷新前,将图像的位置向左移动一个像素,即1px。这样一来,屏幕每次刷出来的图像位置都比前一个要差1px,因此你会看到图像在移动;由于我们人眼的视觉停留效应,当前位置的图像停留在大脑的印象还没消失,紧接着图像又被移到了下一个位置,因此你才会看到图像在流畅的移动,这就是视觉效果上形成的动画。

与setTimeout相比较

理解了上面的概念以后,我们不难发现,setTimeout 其实就是通过设置一个间隔时间来不断的改变图像的位置,从而达到动画效果的。但我们会发现,利用seTimeout实现的动画在某些低端机上会出现卡顿、抖动的现象。 这种现象的产生有两个原因:

  • setTimeout的执行时间并不是确定的。在Javascript中, setTimeout 任务被放进了异步队列中,只有当主线程上的任务执行完以后,才会去检查该队列里的任务是否需要开始执行,因此 setTimeout 的实际执行时间一般要比其设定的时间晚一些。

  • 刷新频率受屏幕分辨率和屏幕尺寸的影响,因此不同设备的屏幕刷新频率可能会不同,而 setTimeout只能设置一个固定的时间间隔,这个时间不一定和屏幕的刷新时间相同。

以上两种情况都会导致setTimeout的执行步调和屏幕的刷新步调不一致,从而引起丢帧现象

requestAnimationFrame:与setTimeout相比,requestAnimationFrame最大的优势是由系统来决定回调函数的执行时机。具体一点讲,如果屏幕刷新率是60Hz,那么回调函数就每16.7ms被执行一次,如果刷新率是75Hz,那么这个时间间隔就变成了1000/75=13.3ms,换句话说就是,requestAnimationFrame的步伐跟着系统的刷新步伐走。它能保证回调函数在屏幕每一次的刷新间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。

除此之外,requestAnimationFrame还有以下两个优势:

  • CPU节能:使用setTimeout实现的动画,当页面被隐藏或最小化时,setTimeout 仍然在后台执行动画任务,由于此时页面处于不可见或不可用状态,刷新动画是没有意义的,完全是浪费CPU资源。而requestAnimationFrame则完全不同,当页面处理未激活的状态下,该页面的屏幕刷新任务也会被系统暂停,因此跟着系统步伐走的requestAnimationFrame也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了CPU开销。

  • 函数节流:在高频率事件(resize,scroll等)中,为了防止在一个刷新间隔内发生多次函数执行,使用requestAnimationFrame可保证每个刷新间隔内,函数只被执行一次,这样既能保证流畅性,也能更好的节省函数执行的开销。一个刷新间隔内函数执行多次时没有意义的,因为显示器每16.7ms刷新一次,多次绘制并不会在屏幕上体现出来。

第八问:web计时,你知道该怎么计算首屏,白屏时间吗?

白屏时间: 白屏时间指的是浏览器开始显示内容的时间。因此我们只需要知道是浏览器开始显示内容的时间点,即页面白屏结束时间点即可获取到页面的白屏时间。

计算白屏时间 因此,我们通常认为浏览器开始渲染 标签或者解析完 标签的时刻就是页面白屏结束的时间点。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>白屏</title>
  <script type="text/javascript">
    // 不兼容performance.timing 的浏览器,如IE8
    window.pageStartTime = Date.now();
  </script>
  <!-- 页面 CSS 资源 -->
  <link rel="stylesheet" href="common.css">
  <link rel="stylesheet" href="page.css">
  <script type="text/javascript">
    // 白屏时间结束点
    window.firstPaint = Date.now();
  </script>
</head>
<body>
  <!-- 页面内容 -->
</body>
</html>
登入後複製

因此白屏时间则可以这样计算出:

可使用 Performance API 时:

白屏时间 = firstPaint - performance.timing.navigationStart;

不可使用 Performance API 时:

白屏时间 = firstPaint - pageStartTime; //虽然我们知道这并不准确,毕竟DNS解析,tcp三次握手等都没计算入内。

首屏时间: 首屏时间是指用户打开网站开始,到浏览器首屏内容渲染完成的时间。对于用户体验来说,首屏时间是用户对一个网站的重要体验因素。通常一个网站,如果首屏时间在5秒以内是比较优秀的,10秒以内是可以接受的,10秒以上就不可容忍了。超过10秒的首屏时间用户会选择刷新页面或立刻离开。

通常计算首屏的方法有

  • 首屏模块标签标记法

  • 统计首屏内加载最慢的图片的时间

  • 自定义首屏内容计算法

1、首屏模块标签标记法

首屏模块标签标记法,通常适用于首屏内容不需要通过拉取数据才能生存以及页面不考虑图片等资源加载的情况。我们会在 HTML 文档中对应首屏内容的标签结束位置,使用内联的 JavaScript 代码记录当前时间戳。如下所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>首屏</title>
  <script type="text/javascript">
    window.pageStartTime = Date.now();
  </script>
  <link rel="stylesheet" href="common.css">
  <link rel="stylesheet" href="page.css">
</head>
<body>
  <!-- 首屏可见模块1 -->
  <div></div>
  <!-- 首屏可见模块2 -->
  <div></div>
  <script type="text/javascript">
    window.firstScreen = Date.now();
  </script>
  <!-- 首屏不可见模块3 -->
  <div></div>
    <!-- 首屏不可见模块4 -->
  <div></div>
</body>
</html>
登入後複製

此时首屏时间等于 firstScreen - performance.timing.navigationStart;

事实上首屏模块标签标记法 在业务中的情况比较少,大多数页面都需要通过接口拉取数据才能完整展示,因此我们会使用 JavaScript 脚本来判断首屏页面内容加载情况。

2、统计首屏内图片完成加载的时间

通常我们首屏内容加载最慢的就是图片资源,因此我们会把首屏内加载最慢的图片的时间当做首屏的时间。

由于浏览器对每个页面的 TCP 连接数有限制,使得并不是所有图片都能立刻开始下载和显示。因此我们在 DOM树 构建完成后将会去遍历首屏内的所有图片标签,并且监听所有图片标签 onload 事件,最终遍历图片标签的加载时间的最大值,并用这个最大值减去 navigationStart 即可获得近似的首屏时间。

此时首屏时间等于 加载最慢的图片的时间点 - performance.timing.navigationStart; //首屏时间尝试: //1,获取首屏基线高度 //2,计算出基线dom元素之上的所有图片元素 //3,所有图片onload之后为首屏显示时间 //

function getOffsetTop(ele) {
    var offsetTop = ele.offsetTop;
    if (ele.offsetParent !== null) {
        offsetTop += getOffsetTop(ele.offsetParent);
    }
    return offsetTop;
}


var firstScreenHeight = win.screen.height;
var firstScreenImgs = [];
var isFindLastImg = false;
var allImgLoaded = false;
var t = setInterval(function() {
var i, img;
if (isFindLastImg) {
if (firstScreenImgs.length) {
for (i = 0; i < firstScreenImgs.length; i++) {
img = firstScreenImgs[i];
if (!img.complete) {
allImgLoaded = false;
break;
} else {
allImgLoaded = true;
}
}
} else {
allImgLoaded = true;
}
if (allImgLoaded) {
collect.add({
firstScreenLoaded: startTime - Date.now()
});
clearInterval(t);
}
} else {
var imgs = body.querySelector(&#39;img&#39;);
for (i = 0; i<imgs.length; i++) {
img = imgs[i];
var imgOffsetTop = getOffsetTop(img);
if (imgOffsetTop > firstScreenHeight) {
isFindLastImg = true;
break;
} else if (imgOffsetTop <= firstScreenHeight && !img.hasPushed) {
img.hasPushed = 1;
firstScreenImgs.push(img);
}
}
}
}, 0);
doc.addEventListener(&#39;DOMContentLoaded&#39;, function() {
var imgs = body.querySelector(&#39;img&#39;);
if (!imgs.length) {
isFindLastImg = true;
}
});




win.addEventListener(&#39;load&#39;, function() {
allImgLoaded = true;
isFindLastImg = true;
if (t) {
clearInterval(t);
}
collect.log(collect.global);
});
登入後複製

解释一下思路,大概就是判断首屏有没有图片,如果没图片就用domready时间,如果有图,分2种情况,图在首屏,图不在首屏,如果在则收集,并判断加载状态,加载完毕之后则首屏完成加载,如果首屏没图,找到首屏下面的图,立刻触发首屏完毕。可以想象这么做前端收集是不准的,但是可以确保最晚不会超过win load,所以应该还算有些意义。。没办法,移动端很多浏览器不支持performance api,所以土办法前端收集,想出这么个黑魔法,在基线插入节点收集也是个办法,但是不友好,而且现在手机屏幕这么多。。

3、自定义模块内容计算法

由于统计首屏内图片完成加载的时间比较复杂。因此我们在业务中通常会通过自定义模块内容,来简化计算首屏时间。如下面的做法:

  • 忽略图片等资源加载情况,只考虑页面主要 DOM
  • 只考虑首屏的主要模块,而不是严格意义首屏线以上的所有内容

实际上用performance.timing来计算首屏加载时间与白屏时间非常简单与精确。不过目前只支持IE10和chrome 贴下其API的使用

var navigationStart = performance.timing.navigationStart;
//1488984540668
console.log(navigationStart);

//Wed Mar 08 2017 22:49:44 GMT+0800 (中国标准时间)
console.log(new Date(new Date(navigationStart)));
复制代码
  redirectStart:到当前页面的重定向开始的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为0
  redirectEnd:到当前页面的重定向结束的时间。但只有在重定向的页面来自同一个域时这个属性才会有值;否则,值为0

console.log(performance.timing.redirectStart);//0
console.log(performance.timing.redirectEnd);//0
  fetchStart:开始通过HTTP GET取得页面的时间

console.log(performance.timing.fetchStart);//1488984540668
  domainLookupStart:开始査询当前页面DNS的时间,如果使用了本地缓存或持久连接,则与fetchStart值相等
  domainLookupEnd:査询当前页面DNS结束的时间,如果使用了本地缓存或持久连接,则与fetchStart值相等

console.log(performance.timing.domainLookupStart);//1488984540670
console.log(performance.timing.domainLookupEnd);//1488984540671
  connectStart:浏览器尝试连接服务器的时间
  secureConnectionStart:浏览器尝试以SSL方式连接服务器的时间。不使用SSL方式连接时,这个属性的值为0 
  connectEnd:浏览器成功连接到服务器的时间

console.log(performance.timing.connectStart);//1488984540671
console.log(performance.timing.secureConnectionStart);//0
console.log(performance.timing.connectEnd);//1488984540719
  requestStart:浏览器开始请求页面的时间
  responseStart:浏览器接收到页面第一字节的时间
  responseEnd:浏览器接收到页面所有内容的时间

console.log(performance.timing.requestStart);//1488984540720
console.log(performance.timing.responseStart);//1488984540901
console.log(performance.timing.responseEnd);//1488984540902
  unloadEventStart:前一个页面的unload事件开始的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为0
  unloadEventEnd:前一个页面的unload事件结束的时间。但只有在前一个页面与当前页面来自同一个域时这个属性才会有值;否则,值为0

console.log(performance.timing.unloadEventStart);//1488984540902
console.log(performance.timing.unloadEventEnd);//1488984540903
  domLoading:document.readyState变为"loading"的时间,即开始解析DOM树的时间
  domInteractive:document.readyState变为"interactive"的时间,即完成完成解析DOM树的时间
  domContentLoadedEventStart:发生DOMContentloaded事件的时间,即开始加载网页内资源的时间
  domContentLoadedEventEnd:DOMContentLoaded事件已经发生且执行完所有事件处理程序的时间,网页内资源加载完成的时间
  domComplete:document.readyState变为"complete"的时间,即DOM树解析完成、网页内资源准备就绪的时间

console.log(performance.timing.domLoading);//1488984540905
console.log(performance.timing.domInteractive);//1488984540932
console.log(performance.timing.domContentLoadedEventStart);//1488984540932
console.log(performance.timing.domContentLoadedEventEnd);//1488984540932
console.log(performance.timing.domComplete);//1488984540932
  loadEventStart:发生load事件的时间,也就是load回调函数开始执行的时间 
  loadEventEnd:load事件已经发生且执行完所有事件处理程序的时间

console.log(performance.timing.loadEventStart);//1488984540933
console.log(performance.timing.loadEventEnd);//1488984540933
登入後複製

第九问:你知道web Worker吗?

多线程技术在服务端技术中已经发展的很成熟了,而在Web端的应用中却一直是鸡肋 在新的标准中,提供的新的WebWork API,让前端的异步工作变得异常简单。 使用:创建一个Worker对象,指向一个js文件,然后通过Worker对象往js文件发送消息,js文件内部的处理逻辑,处理完毕后,再发送消息回到当前页面,纯异步方式,不影响当前主页面渲染。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script type="text/javascript">
        //创建线程 work对象
        var work = new Worker("work.js");      //work文件中不要存在跟ui代码
        //发送消息
        work.postMessage("100");
        // 监听消息
        work.onmessage = function(event) {
            alert(event.data);
        };
    </script>
</head>
<body>
 
</body>
</html>
登入後複製

work.js

  onmessage = function (event) {
    //从1加到num
    var num = event.data;
    var result = 0;
    for (var i = 1; i <= num; i++) {
        result += i;
    }
    postMessage(result);
}
登入後複製

(学习视频分享:web前端入门jQuery视频教程

以上是【進階技巧】九個前端面試題,帶你鞏固知識點!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP與Vue:完美搭檔的前端開發利器 PHP與Vue:完美搭檔的前端開發利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Django是前端還是後端?一探究竟! Django是前端還是後端?一探究竟! Jan 19, 2024 am 08:37 AM

Django是一個由Python編寫的web應用框架,它強調快速開發和乾淨方法。儘管Django是web框架,但要回答Django是前端還是後端這個問題,需要深入理解前後端的概念。前端是指使用者直接和互動的介面,後端是指伺服器端的程序,他們透過HTTP協定進行資料的互動。在前端和後端分離的情況下,前後端程式可以獨立開發,分別實現業務邏輯和互動效果,資料的交

前端面試官常問的問題 前端面試官常問的問題 Mar 19, 2024 pm 02:24 PM

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。

Go語言前端技術探秘:前端開發新視野 Go語言前端技術探秘:前端開發新視野 Mar 28, 2024 pm 01:06 PM

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

Django:前端和後端開發都能搞定的神奇框架! Django:前端和後端開發都能搞定的神奇框架! Jan 19, 2024 am 08:52 AM

Django:前端和後端開發都能搞定的神奇框架! Django是一個高效、可擴展的網路應用程式框架。它能夠支援多種Web開發模式,包括MVC和MTV,可以輕鬆地開發出高品質的Web應用程式。 Django不僅支援後端開發,還能夠快速建構出前端的介面,透過模板語言,實現靈活的視圖展示。 Django把前端開發和後端開發融合成了一種無縫的整合,讓開發人員不必專門學習

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

Golang與前端技術結合:探討Golang如何在前端領域發揮作用 Golang與前端技術結合:探討Golang如何在前端領域發揮作用 Mar 19, 2024 pm 06:15 PM

Golang與前端技術結合:探討Golang如何在前端領域發揮作用,需要具體程式碼範例隨著互聯網和行動應用的快速發展,前端技術也愈發重要。而在這個領域中,Golang作為一門強大的後端程式語言,也可以發揮重要作用。本文將探討Golang如何與前端技術結合,以及透過具體的程式碼範例來展示其在前端領域的潛力。 Golang在前端領域的角色作為一門高效、簡潔且易於學習的

See all articles