Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
PI
來源:快舔包我很肥
框架
WebAPI Contrib:幫助你提高 ASP.NET Web API 能力的開源項目集合。
應用框架(Application Frameworks)
應用模板(Application Templates)
人工智能(Artificial Intelligence)
程序集處理(Assembly Manipulation)
資源(Assets)
認證和授權(Authentication and Authorization)
自動構建(Build Automation)
緩存(Caching)
CLI
CLR
CMS
代碼分析和度量(Code Analysis and Metrics)
編譯器(Compiler)
壓縮(Compression)
持續集成(Continuous Integration)
加密(Cryptography)
數據庫(Database)
數據庫驅動(Database Drivers)
反編譯(Decompilation)
部署(Deployment)
DirectX
分布式計算(Distributed Computing)
文檔(Documentation)
電子商務和支付(E-Commerce and Payments)
環境管理(Environment Management)
ETL
游戲(Game)
地理信息系統(Gis)
Git工具(Git Tools)
圖形(Graphics)
GUI
HTML 和 CSS(HTML and CSS)
HTTP
IDE
圖像處理(Image Processing)
安裝工具(Install Tools)
國際化(Internationalization)
互操作(Interoperability)
IoC
日志(Logging)
機器學習和數據科學(Machine Learning and Data Science)
Markdown 處理(Markdown Processors)
郵件(Mail)
數學(Mathematics)
多媒體(Media)
度量(Metrics)
微框架(Micro Framework)
雜項(Misc)
MVVM
Office
ORM
包管理(Package Management)
Profiler
推送通知(Push Notifications)
隊列(Queue)
響應式編程(Reactive Programming)
計劃調度(Scheduling)
SDK 和 API 客戶端(SDK and API Clients)
搜索(Search)
序列化(Serialization)
狀態機(State machines)
靜態網站生成(Static Site Generators)
風格指南(Style Guide)
模板引擎(Template Engine)
測試(Testing)
交易(Trading)
Visual Studio 插件(Visual Studio Plugins)
Web 框架(Web Frameworks)
Web 服務器(Web Servers)
WebSocket
Windows 服務(Windows Services)
通訊框架(Communication Frameworks)
其他列表(Other Lists)
看完本文有收獲?請轉發分享給更多人!!!歡迎大家點贊,留言討論,喜歡這篇文章可以分享給更多人,關注我每天更新分享有關程序員、科技、編程之類的文章!!!愛你們,,么么噠,,讓我們一起愉快的玩耍把!!!
要說 js 的深淺拷貝,就不得不提 js 的兩大數據類型:基本數據類型和引用類型。基本數據類型的變量名和值都存儲在棧中,對于引用類型的變量名存儲在棧中,而值存儲在堆中。由于存儲方式不同,所以導致了他們復制的時候方式不同。
淺拷貝是創建一個新對象,這個對象有著原始對象屬性值的一份精準拷貝。如果屬性是基本類型,拷貝的就是基本類型的值,如果是引用類型,拷貝的就是內存地址,所以如果其中一個對象改變了這個地址,就會影響到另外一個對象。
深拷貝是將一個對象從內存中完整的拷貝一份出來,從內存堆中存放一個新的對象。這是兩個對象,所以修改其中一個,另外一個不會受影響。
深淺拷貝主要針對的是引用類型,簡單數據類型不受影響。
相關筆試題
var person = {
name:"前端人",
hobby:['學習','敲代碼','潛水']
}
function copy(source){
var newObj = new Object()
for(var i in source){
if(source.hasOwnProperty(i)){
newObj[i] = source[i]
}
}
return newObj
}
var p1 = copy(person);
p1.name = "Web Person"
console.log(person.name)
console.log(p1.name)
p1.hobby = ["內卷"]
console.info(person.hobby)
console.info(p1.hobby)
/*運行結果:
前端人
Web Person
["學習", "敲代碼", "潛水"]
["內卷"]
*/
js 數據類型一共有 8 種,分為兩大類:基本類型和引用類型。
它們的數據類型分別為:
基本類型:string、number、boolean、null、undefined、symbol、bigint
引用類型:object
相關面試題
// 注意:其他類型與數值進行相加時,其他類型的轉為 number 類型
console.log( true+1 ) // 2
console.log( undefined +1 ) // NaN
console.log( null ) //object
console.log( undefined ) // undefined
共有 6 種方式,分別為:
它們的區別介紹:
1、async:為 <script>標簽定義了 async 屬性。async 和 html 解析是同步的,不是順次執行 js 腳本,誰先加載完成先執行誰。
<script async type="text/javascript" src="demo1.js" ></script>
<script async type="text/javascript" src="demo2.js" ></script>
2、defer 會等到 html 解析完成之后再執行 js 代碼,如果有多個腳本時,會按照順序依次執行腳本。
<script defer type="text/javascript" src="demo1.js" ></script>
3、js 最后加載
把 js 外部引入的文件放置在頁面的底部,讓 js 最后加載,從而加快頁面加載速度。
4、利用 setTimeout
5、動態創建 DOM 的方式
var element = document.createElement("script");
element.src = "box.js";
document.body.appendChild(element);
這種方式通過操作動態加載 js 文件,不觸發的時候不加載,減少頁面文件大小,加快加載速度。
6、使用 jQuery 的 getScript 方法
$.getScript( "box.js",function(){//回調函數,成功獲取文件后執行的函數
console.log("腳本加載完成")
});
相關面試題:
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="box.js"></script>
</head>
<body>
<div id="box"></div>
</body>
</html>
//box.js 代碼如下
console.log( document.getElementById('box') ) // null
box.js 想正常獲取元素 box ,并進行一系列操作應該如何延遲加載 js 文件呢?
作用域通俗地講,就是指一個變量的作用范圍。分為全局作用域和函數作用域。
全局作用域
函數作用域(局部)
函數在被調用的時候會先進行預編譯:
全局作用域預編譯:
函數作用域預編譯:
相關面試題:
<script type="text/javascript">
function fn(a,c){
console.log(a)
var a = 12
console.log(a)
console.log(c)
function a(){ }
if(false){
var d = 34
}
console.log(d)
console.log(b)
var b = function(){}
console.log(b)
function c(){}
console.log(c)
}
fn(1,2)
</script>
// 運行結果:
/*
function a(){}
12
function c(){}
undefined
undefined
function (){}
function c(){}
*/
null 和 undefined 兩個都表示無的值。
作者設計 js 的時候,借鑒的 java 語言先設計的 null 。null 使用的時候會被隱式轉化成 0,不容易發現錯誤。
console.log( number(null) ) //0
undefined 是為了填補 null 的坑。所以后來又新增了 undefined 。
console.log( number(undefined) ) //NaN
實現 new 操作符的方法:
function create( fn,...args ){
var obj={}
Object.setPrototypeOf( obj,fn.prototype )
var resault = fn.apply(obj,args)
return (resault instanceof Object) ? result : obj
}
7.1、什么是閉包?
閉包就是函數嵌套函數,通過函數內的函數訪問變量的規則,實現外部訪問函數內的變量。
7.2、閉包的特點:
實例3:閉包解決問題
var liArr = document.getElementsByTagName('li')
for(var i=0;i<liArr.length;i++){
(function(i){
liArr[i].onclick = function(){
console.log('點擊元素',liArr[i])
}
})(i)
}
7.3、閉包優點:
防抖和節流就是閉包的經典應用。
7.4、閉包缺點:
8.1、什么是防抖函數?
當持續觸發事件,一定時間內沒有再觸發事件,事件處理函數才會執行一次,如果在設定的時間到來之前又觸發了事件,就會重新計時。
防抖函數常見的實際應用:使用 echart 的時候,瀏覽器 resize 時,需要重新繪制圖表大小,還有典型的輸入框搜索應用。
8.2、節流函數是什么?
當持續觸發事件的時候,保證一段時間內只調用一次事件處理函數,一段時間內,只允許做一件事情。
防抖和節流主要是用來限制觸發頻率較高的事件,再不影響效果的前提條件下,降低事件觸發頻率,減小瀏覽器或服務器的壓力,提升用戶體驗效果。
方法1: new set()
return Array.from(new Set(arr))
// 或
return [...new Set(arr)]
方法2:使用兩次循環
for(var i=0,len=arr.length;i<len;i++){
for(var j=i+1,len=arr.length;j<len;j++){
if( arr[i]===arr[j] ){
arr.splice(i,1)
j--;
len--
}
}
}
return arr
方法3:indexOf 實現
let arr1 = []
for(var i=0;i<arr.length;i++){
if( arr1.indexOf(arr[i]) === -1 ){
arr1.push(arr[i])
}
}
return arr1
方法4:includes 實現
let arr1 = []
for(var i=0;i<arr.length;i++){
if( !arr1.includes(arr[i]) ){
arr1.push(arr[i])
}
}
return arr1
方法5:filter 實現
array.indexOf(item,start) start 表示開始檢索的位置。
return arr.filter(( item, index )=>{
return arr.indexOf( item, 0 ) == index
})
三者都是改變函數執行的上下文,即改變 this 指向。
它們之間的區別為:
使用場景:
1、需要改變某個函數的this指向時
2、當參數較少時可以使用call,參數較多可以使用apply以數組的方式傳遞
3、當需要重復調用時,可以使用bind新定義一個方法
方法1:isArray
var arr = [1,2,3]
console.log(Array.isArray(arr))
方法2:instanceof
var arr = [1,2,3]
console.log( arr instanceof Array )
console.log( arr instanceof Object )
該方法不夠嚴謹。
方法3:prototype
console.log( Object.prototype.toString.call(arr).indexOf('Array')>-1 )
方法4:isPrototypeOf
console.log( Array.prototype.isPrototypeOf( arr ) )
方法5:constructor
console.log(arr.constructor.toString().indexOf('Array')>-1 )
slice 是用來截取字符串的,返回一個新數組,但不會影響原數組。
使用語法:
arr.slice( start , end )
截取 arr 數組,從 start 開始到 end 結束,第二個參數是可選參數,沒有時從 start 開始截取到結尾。
如果 start 參數是負數時,就會從 arr.lengtn + start 開始截取到結束。
var arr = ['a','b','c','d','e']
console.log( arr.slice(-3) ) // ["c", "d", "e"]
console.log(arr) //["a", "b", "c", "d", "e"]
splice 是一個更強大的方法,可以添加、刪除、替換數組元素,返回的是被刪除元素,它的操作會改變原數組。
使用語法:
splice( start, n, new )
從 start 開始,刪除 n 個元素,然后把 new 添加到 start 元素之后。第三個參數為可選參數
var arr = ['a','b','c','d','e']
var ar = arr.splice( 1, 1 ,'f','g')
console.log('ar',ar) // ["b"]
console.log('arr',arr) // ["a", "f", "g", "c", "d", "e"]
== 比較的是值,=== 除了比較值,還比較類型。
console.log( [1,2]=='1,2' ) // true
console.log( [1,2] === '1,2' ) //false
valueOf 方法返回 Math 對象的原始值,通常由 javascript 在后臺自動調用,并不顯示的出現在代碼中。
console.log([1,2].valueOf()) //[1,2]
console.log('1,2'.valueOf()) //[1,2]
// 所以
console.log( [1,2]=='1,2' ) // true
不管是字符串和數字比較,還是布爾值和數字比較,都會使用 valueOf 隱式轉換。
總結:== 需要使用 valueOf() 進行隱式轉換,所以性能差。 === 會避開一些不必要的麻煩。
大廠筆試題:
var name = 'window name'
var p1 = {
name:'p1 name',
showName:function(){
console.info(this.name)
}
}
var fn = p1.showName
fn()
p1.showName()
var p2 = {
name:'p2 name',
showName:function(fun){
fun()
}
}
p2.showName(p1.showName)
p2.showName = p1.showName
p2.showName()
/*
運行結果:
window name
p1 name
window name
p2 name
*/
這是一道關于 this 指向的面試題,接下來我們就說說 this 是如何指向的?
this 對象是運行時基于函數的執行環境綁定的:
第 1 種:原型鏈繼承
function Parent(){
this.name = "前端人"
}
Parent.prototype.showName = function(){
console.log(this.name)
}
function Child(){}
//原型鏈繼承
Child.prototype = new Parent()
var p = new Child()
console.dir(p.name) //前端人
特點:
第 2 種:借用構造函數
function Animal (name) {
this.name = name || 'Animal';
this.sleep = function(){
console.log(this.name + '正在睡覺!');
}
}
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
特點:
還有組合式繼承、ES6 的繼承 和 寄生組合繼承等等。每種繼承方式都有各自的特點和缺點。
JavaScript 語言是一門弱類型語言,存在許多類型錯誤,因此 ES6 引入了嚴格模式概念。
如果不加 ‘use strict’ 常規模式下就是屬于非嚴格模式。
嚴格模式
在 js 文件頂部添加 ‘use strict’ 就屬于嚴格模式,嚴格模式也可以指定在函數內部。
<script>
'use strict'
//或者函數內部
(function(){
'use strict'
})()
</script>
嚴格模式,是為 js 定義來了一種不同的解析與執行模型,在嚴格模式下,ECMAScipt 3 中一些不解和不確定的行為將得到處理,而且會對不安全的操作會拋出異常。‘use strict’ 會告訴瀏覽器引擎可以切換到嚴格模式執行。
嚴格模式與非嚴格模式區別
嚴格模式 | 非嚴格模式 |
變量必須聲明才能賦值 | 變量不進行聲明,可直接賦值 |
不能使用 delete 字符刪除變量或對象 | 可以使用 delete 刪除 |
函數參數變量名不允許重復 | 變量名重復,獲取最后最后那個值 |
普通函數內的 this 為 undefined | 普通函數內的 this 為 window |
不允許使用八進制 | 允許任意進制 |
eval 和 arguments 當做關鍵字,不能被賦值和用作變量名 | 可以使用 eval 、arguments 作為變量名 |
call、apply 傳入 null undefined 保持原樣不被轉為window | 默認轉為 window 對象 |
限制對調用棧的檢測能力,訪問 arguments.callee 會拋出異常 | arguments.callee 運行正常 |
console.log( '2'>10 ) //false
console.log( '2'>'10' ) //true
console.log( 'abc'>'b' ) //false
console.log( 'abc'>'aab' ) //true
console.log( undefined == null ) //true
console.log( NaN == NaN )//false
console.log( [] == 0 ) //true
console.log( ![] == 0 ) //true
console.log( [] == [] ) //false
console.log( {} == {} ) //false
console.log( {} == !{} ) //false
阿里面試題1:
<script type="text/javascript">
var p =new Promise(resolve=>{
console.log(4)
resolve(5)
})
function f1(){
console.log(1)
}
function f2(){
setTimeout(()=>{
console.log(2)
},0)
f1()
console.log(3)
p.then(res=>{
console.log(res)
})
}
f2()
</script>
// 運行結果 4 1 3 5 2
// 如果已經了解事件運行機制,就可以跳過該問題了
事件循環機制,event-loop 。包含三部分:調用棧、消息隊列、微任務隊列。
事件循環開始的時候,會從全局一行一行的執行代碼,遇到函數調用的時候,就會壓入調用棧中,當函數執行完成之后,彈出調用棧。
// 如:代碼會一行一行執行,函數全部調用完成之后清空調用棧
function f1(){
console.log(1)
}
function f2(){
f1()
console.log(2)
}
f2()
// 執行結果 1 2
如果遇到 fetch、setInterval、setTimeout 異步操作時,函數調用壓入調用棧時,異步執行內容會被加入消息隊列中,消息隊列中的內容會等到調用棧清空之后才會執行。
// 如:
function f1(){
console.log(1)
}
function f2(){
setTimeout(()=>{
console.log(2)
},0)
f1()
console.log(3)
}
f2()
// 執行結果 :1 3 2
遇到 promise、async、await 異步操作時,執行內容會被加入微任務隊列中,會在調用棧清空之后立即執行。
調用棧加入的微任務隊列會立即執行。
如
let p =new Promise(resolve=>{
console.log('立即執行')
resolve(1) //在 then 調用中執行
})
微任務隊列中內容優先執行,所以比消息隊列中的內容執行得早。
了解這些知識后,再試一下最前面的那道面試題,應該就沒什么問題了。
這個問題就留給讀到最后,能夠堅持學習的人,問問我們自己有什么是我們擅長的?在哪塊領域是我們占據競爭優勢的?
.昨日回顧
編號 | 姓名 | 性別 | 學歷 | 畢業院校 |
1 | 張三 | 男 | 大專 | 中國人民大學 |
2 | 李四 | |||
3 |
<table>
<tr>
<th>編號</th>
<th>標題</th>
<th>發布日期</th>
</tr>
<tr>
<td>1</td>
<td>重蔚自留地</td>
<td>2014-10-20</td>
</tr>
</table>
如果使用表格來排版網頁,搜索引擎搜互的幾乎很低。
DIV+CSS布局或排版網頁,層級一般為3層左右。
HTML網頁是一個結構化的文檔,是一按層次順序展示的一個文檔。
<table>的子元素(標記)是<tbody>,而不是<tr>;
<tr>是<tbody>的子元素
2.表單
1、表單的主要功能:就是用來搜索用戶信息。
2、表單的工作原理
用戶填寫有表單的網頁,單擊某個按鈕進行提交;
用戶填寫的表單數據,將發到服務器;
服務器上有專門的程序來對用戶提交的數據進行驗證;
如果有錯誤,服務器會返回給瀏覽器一個錯誤信息;
如果沒有錯誤,PHP程序會將用戶提交的數據寫入數據庫,并返回一個成功的信息。
補充:
用戶輸入的信息是否正確,比如:郵箱地址、電話號碼、用戶名是否重名等
這些信息都是由PHP后臺程序來做驗證。
3、<form>標記:是一組標記(多個標記)
<form name=“form1” action=“login.php”>
用戶名:<input type=“text” name=“username” size=“50” />
密碼:<input type=“password” name=“password” size=“50” />
<input type=“submit” name=“submit” value=“提交” />
</form>
注意:所有表單元素都必須放在<form>中,然后一起提交給服務器。
<form>的常用屬性
Name:指表單的名稱,這個名稱一般給JS或PHP來用。
比如:要獲取“用戶名”框中輸入的信息,用JS獲取是:document.form1.username.value
Action:設置表單數據的處理程序文件名;比如:login.php
Method:表單數據的提交方式。有兩種方式:GET和POST
默認的提交方式:就是GET方式。
GET方式:將表單中的數據(以“名稱/值”)形式,追加到表單處理程序(action指定)的末尾。
缺點:提交少量信息、不太安全、只能提交簡單的數據,一般可以提交100個字節內的數據
http://www.sina.com.cn/news.php?id=234
POST方式:將表單數據直接發放ACTION指定的處理程序,并沒有在地址欄顯示。
優點:提交海量數據、相對比較安全、提交的數據類型多樣化
Enctype:是指表單數據的編碼方式(加密方式)
Application/x-www-form-urlencoded 普通的加密方式(默認)
Multipart/form-data 只有上傳文件時使用。
單行文本框:用戶名、地址、聯系方式、郵編等
<input type=“text” name=“名稱” value=“默認值” size=“多少個字符寬” maxlength=“最多可放多少個字符” />
注意:如果要把表單元素排齊,請使用表格來排,排的順序是<form>標記中嵌<table>,<td>中放每一個表單元素。
2、單行密碼框:密碼框中的內容是以“*”號顯示,是為了保證數據的安全
<input type=“password” name=“名稱” size=“字符寬” maxlength=“最大字符數” />
3、按鈕
提交銨鈕:<input type=“submit” name=“submit” value=“提交按鈕” />
重置按鈕(清空):<input type=“reset” name=“reset” value=“重新填寫” />
圖片按鈕:<input type=“image” src=“圖片URL” value=“值” />
注意:圖片按鈕默認是提交表單
普通按鈕:<input type=“button” name=“名稱” value=“按鈕文本” />
<input type="button" value="普通按鈕" onclick="javascript:this.form.reset()" />
注意:普通按鈕沒有任何功能,一般要結合JS來實現提交或重置。
提示:如果哪一個表單項,不想讓它提交到服務器,請不要給它添加name屬性即可。
4、單選按鈕:一組相互排斥的按鈕,也就是每一次只能選擇一個。
<input type=“radio”name=“名稱” value=“值”checked=“checked” />男
注意:一組單選按鈕的name值是一樣的,最后只能提交選中的哪一個。
5、復選框:一組復選框的名稱也是一樣的,在后臺獲取值時,將使用“數組”的形式來獲取。
<input type=“checkbox”name=“名稱”value=“值”checked=“checked” />游戲
注意:復選框可以同時選擇多個,也可以一個都不選。
提示:數組是一個名字里,可以存放多個不同的值(了解)
JS數組:Var hobby = [“游戲”,“美術”,“電腦”]
6、下拉列表
<select name=“edu”>
<option value=“” selected=“selected”>請選擇……</option>
<option value=“高中”>高中</option>
<option value=“大專”>大專 </option>
</select>
7、文本區域
<textarea name=“名稱”rows=“幾行高”cols=“多少個字符寬”></textarea>
提示:如果要在<textarea>中插入圖片,實現圖文混排,這個標記做不到。一般網站的效果都是通過“在線HTML代碼編回器”實現的。比如:FCKEdit(就業班講)
8、上傳文件
<input type=“file”name=“uploadFile” />
注意:value屬性是只讀屬性,是為了保證網站的安全。
GET方式上傳不了文件,
只有POST能上傳文件,并且編碼類型設置為:mulitpar/form-data
3.框架
1、框架的概念:將一個瀏覽器窗口劃分若干個區域,每個區域都是一個獨立的小窗口,小窗口中存放一個網頁文件。
框架相當于一個窗戶。一個窗戶由窗格和玻璃構成。一個框架是由框架集(Frameset)和框架頁(Frame)構成。
<frameset>中定義框架的結構(上下型、左右型)、大小、位置等。
<frame>中定義小窗口是否顯示滾動條、小窗口是否可以改大小、默認顯示的網頁
在框架定義頁面中,不能出現<body>及<body>的子標記,換句話說,<frameset>和<body>只能選擇其中一個。
2、框架的代碼結構
<frameset>
<frame />
<frame />
</frameset>
3、<frameset>的常用屬性
Rows:指定框架為上下型,例如:rows=“180,*”,上窗口的高為180px,剩下都給下窗口。
Rows=“180,20,*”,頂窗口高為180px,中窗口高為20px,剩下高都給下窗口。
Rows=“20%,50%,*”
Cols:劃分框架為左右型,例如:cols=“200,*”,左窗口寬為200px,剩下都給右窗口。
Cols=“200,10,*”
Frameborder:是否顯示框架邊線,取值:1或0,yes或no
Border:指定邊框的粗細
Bordercolor:邊框的顏色
Framespacing:指框架邊框間的距離
4、<frame>的常用屬性:主要定義:是否可以調整大小、是否顯示滾動條、默認頁設置
Src:設置小窗口中顯示的默認網頁;
Noresize:是否可以調整窗口的大小,取值:noresize
Scrolling:是否顯示滾動條,取值:yes、no、auto(自動)
Name:設置每個小窗口的
Index.html
4.行內框架<iframe></iframe>
<iframe>是<body>的子元素
<ifame>是嵌套到<body>元素中的。
常用屬性
Src:引入哪個HTML文件
Width:指行內框架的寬度
Height:指行內框架的高度
Scrolling:是否顯示滾動條
Align:水平對齊方式
*請認真填寫需求信息,我們會在24小時內與您取得聯系。