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小时内与您取得联系。