又到了跳槽的季节,如今也该总结一下本身在前端积累这么多年的一点珍藏的货色了,注意了我主要总结是尽可能用本身能表达的想法去说,全部可能没别人总结的那么客观,还有尽可能用简短的话简单的思路去表达应该有的意思,方便记忆理解,还有这篇博文我会持续更新的javascript
.transition{ -webkit-transition: all .5s; -moz-transition: all .5s; -o-transition: all .5s; transition: all .5s; }//渐进加强 .transition{ transition: all .5s; -o-transition: all .5s; -moz-transition: all .5s; -webkit-transition: all .5s; }//优雅降级优雅降级:一开始就构建完整的功能,而后再针对低版本浏览器进行兼容php
渐进加强:针对低版本浏览器进行构建页面,保证最基本的功能,而后再针对高级浏览器进行效果.交互等改进和追加功能达到最好的用户体验css
(functon(window,undefined){})(window)html
jQuery利用JS函数做用域的特性,采用当即调用表达式包裹了自身,解决命名空间和变量污染问题前端
window.jQuery=window.$=jQueryvue
在闭包当中将jQuery和$()绑定到window上,从而jQuery和$暴露为全局变量java
jQuery.fn的init方法返回的this就是jQuery对象node
核心是对DOM
操做进行的封装,以免单独实现不一样浏览器的兼容代码jquery
经过代理对象,给不一样的对象监听事件,进行管理webpack
浅拷贝(只复制一份原始对象的引用)
- var newObject=$.extend({},oldObject)
深拷贝(对原始对象实行所引用的对象进行递归拷贝)
JSON对象parse方法能够将JSON字符串反序列化成js对象,stringify方法能够将js对象序列化成json字符串,这两种方法产生一个便捷的深克隆
- var newObject=$.extend(true,{},oldObject)
深拷贝以后,改变其中一个值,不会影响另一个值,浅拷贝则会影响
浅拷贝只是拷贝了指向对象的指针
而深拷贝则是彻底拷贝整个值,建立了一个新的和原对象同样的对象
第一种
overflow:hidden
第二种
.clearfix:after{ content:".", diplay:block; hieght:0; clear:both; visibility:hidden; }
var arr=[1,2,12,5,6]; Math.max(...arr);//es6 math.max.apply(null,arr)//es5 apply //for循环 let max=arr[0]; for(let i=0;i<arr.length-1;i++){ max=arr[i]<arr[i+1]?arr[i+1]:arr[i] } //数组sort() arr.sort((num1,num2)=>{return num1-num2<0})//回忆a-b升序b-a降序,同理喔 arr[0] //数组reduce //这个仍是须要科普一下 //aray的reduce()把一个函数做用在整个Array的[x1,x2,x3,x4...]上,这个必须接受两个 //参数,reduce()把结果继续和序列的下一个元素作累计计算,怎么感受有点像map //感受没有解释清楚,下面给个地址 arr.reduce((num1,num2){return num1>num2?num1:num2})
[... new Set([2,"23","2","5",12,5,6,12])]
最快速的方式
- 最简单的方法
function arr1(){ var n=[]; for(var i=0;i<arr.length;i++){ if(n.indexOf(arr[i])==-1){ n.push(arr[i]) } } return n; }
cookie是网站为了标识用户身份而存储在用户本地终端上的数据
cookie数据使用在同源的http请求中携带,会在浏览器和服务器来回传递
webStorage目的:克服cookie带来的一些限制,当数据须要被严格控制在客户端是,不须要持续的将数据发回服务器
webstorage提供两种API:localstorage(本地存储)和sessionStorage(会话存储)
生命周期:
localStorage(本地存储)
- 永久的,关闭网页也不会消失,除非主动删除数据sessionStorage(会话存储)
- 数据在当前浏览器窗口关闭后自动删除cookie 设置的cookie过时时间以前一直有效,即便浏览器关闭
locaStorage(本地存储)和sessionStorage(会话存储)不会自动把数据发给服务器,仅仅本地保存
存储大小:
- cookie -->4k
- sessionStorage和localStorage -->5m或更大
栈:原始数据类型(undefined,null,Boolean,number,string)
堆:引用数据类型(对象,数组,函数)
区别:存储位置不一样
原始类型数据直接存储在栈的简单数据段
- 占据空间小,大小固定,属于被平凡使用数据,因此放在栈中存储
引用数据类型存储在堆中的对象
- 占据空间大,大小不固定,
若是存储在栈中,将会影响程序运行的性能
- 引用数据类型在栈中存储了指针,该指针指向该实体的起始地址
- 当解释器寻找引用值时,会首先检索在栈中的地址,取得地址后从堆中获取实体
原型prototype机制或apply和call方法去实现较简单,建议使用构造函数与原型混合方式。 function Parent(){ this.name = 'wang'; } function Child(){ this.age = 28; } Child.prototype = new Parent();//继承了Parent,经过原型 var demo = new Child(); alert(demo.age); alert(demo.name);//获得被继承的属性
DTD就是告诉浏览器我是什么文档类型,用这个来判断我用什么来解析它渲染它
doctype就是通知浏览器哪一个DTD和文档类型
<!doctypehtml>
--->HTML5
HTML4.0有两个模式:严格模式和宽松模式
分为两个部分:渲染引擎和js引擎
渲染引擎:负责取得网页的内容(html,css)
js引擎:解析和执行javascript来实现网页的动态效果,可是后来js引擎愈来愈独立了(V8引擎)
var a=[1,2,34,4,5,6,76,7,1,2,3,4,5,6,7] sun=null; sun=a.slice(0,10).reduce(function(pre,current){ return pre+current; }) console.log(sun);//reduce能够看前面最大值
松耦合:当修改一个组件而不须要改其余组件时,就作到松耦合
将js从css中抽出,不要使用css表达式
将css从js中抽出:经过js修改css样式时,使用className或classList
将js从html抽离:从js外置文件
将HTML从js中抽离:不要使用innerHTML使用字符串模板
HTML.css.JS三者的关系应当时相互独立分离的,若是产生交集,出现紧耦合代码,就违反了代码可维护性原则
全局变量
零全局变量(function(){})(window)
单全局变量(jQuery)和命名空间
模块
事件处理
隔离应用逻辑(将应用逻辑和事件处理的代码拆分开)
var MyApplication = { handleClick: function(event){ this.showPopup(event); }, showPopup: function(event){ var popup = document.getElementById('popup'); popup.style.left = event.clientX + 'px'; popup.style.top = event.clientY + 'px'; popup.className = 'reveal'; } }; addListener(element,'click',function(event){ MyApplication.handleClick(event); });
不要分发事件对象
让事件处理程序使用event对象来处理事件,而后拿到全部须要的数据传到应用逻辑
//改进的作法 var MyApplication = { handleClick: function(event){ this.showPopup(event.clientX,event.clientY); }, showPopup: function(x,y){ var popup = document.getElementById('popup'); popup.style.left = x + 'px'; popup.style.top = y + 'px'; popup.className = 'reveal'; } }; addListener(element,'click',function(event){ MyApplication.handleClick(event); });
记得在事件处理程序应当在进入应用逻辑以前针对event对象执行任何须要的操做,包括阻止时间冒泡,都应该包含在事件处理程序中
//改进的作法 var MyApplication = { handleClick: function(event){ event.preventDefault(); event.stopPropagation(); this.showPopup(event.clientX,event.clientY); }, showPopup: function(x,y){ var popup = document.getElementById('popup'); popup.style.left = x + 'px'; popup.style.top = y + 'px'; popup.className = 'reveal'; } }; addListener(element,'click',function(event){ MyApplication.handleClick(event); });
感受这个须要日积月累,感受前面是有无数的坑等着你踩先完成功能而后再考虑优化的问题
node进程启动事后默认会建立一个线程,线程用于执行咱们的代码
一个进程能够有多个线程,全部进程与线程是包含与被包含的关系
进程(程序):一个静态概念,一个class文件,一个exe文件
线程:是一个程序里面不一样的执行路径
先序遍历:顺序根左右
中序遍历:顺序左根右
后序遍历:顺序左右根
层序遍历:顺序从上到下从左到右分层遍历
前序遍历:先访问根节点,而后前序遍历左子树,再前序遍历右子树(中左右)
中序遍历:从根节点开始(注意不是先访问根节点),中序遍历根节点的左子树,而后是访问根节点,左后遍历根节点的右子树(左中右)
这里仍是要多罗嗦一些东西,由于我有时仍是有点不太懂(这样是否是稍微清晰了一点)
中序遍历:BDCAEHGKF
后序遍历:从左到右先叶子后节点的方式遍历访问根节点(左右中)//怎么有点像css遍历从上到下从右到左
层序遍历:从树的第一层,也就是根节点开始访问,从上到下逐层遍历,在同一层中,按从左到右的顺序结构访问
当浏览器获取html文件时,会"自上而下"加载,并在加载过程解析渲染
解析:
浏览器会将HTML解析成一个DOM树,DOM树的构建过程是一个深度遍历过程:当前节点的全部子节点都构建好后才会去构建当前节点的下一个兄弟节点
将CSS解析成CSS Rule Tree
根据DOM树和CSSOM树来构造Rendering Treen,注意:Rendering Tree渲染树并不等同于DOM树,由于一些想header或display:none的东西就不必放在渲染树中
有了Render Tree,浏览器已经能知道网页中有哪些节点.各个节点的CSS定义以及他们的从属关系,下一步操做称之为Layout就是计算出每一个节点在屏幕中的位置
而后就进行绘制,遍历render树,并使用UI后端层绘制每个节点
终于说到重点了,影响浏览器渲染主要有:reflow(回流)和repaint(重绘)
回流Reflow(渲染机制类)
- DOM结构中的各个元素都有本身的盒子模型,这些须要浏览器根据各类样式计算并根据计算结果将元素放在该出现的位置,这个过程称reflow
触发Reflow
移动DOM
修改CSS
修改网页默认字体
增长删除修改DOM节点
重绘Repaint
- 页面呈现的内容放在页面上
触发Reqaint
DOM改动
CSS改动
尽可能避免reflow(回流)
reflow想一想怎么可能避免呢?那只能将reflow对性能的影响减到最小
好比须要改变元素的样式,不要经过父级元素影响子元素,最好直接加载子元素
设置style属性改变样式的话,没设置一次都会致使一次reflow,最好就是设置class的方式
避免没必要要的复杂的css选择器,尤为是后代选择器(这里确定会有人反驳了,我用的是less,就看看解析的时候,后代有多长,看着多怕,哥们要不你用sess或者sass,有个属性能够直接跳出选择器
@at-root
less有没有我也不知道)还有就是不要用tables布局
从数组中移出falsey值
使用Array.filter()删选出falsey值(false,null,0,"",undefined和NaN)
const compact=arr=>arr.filter(Boolean); console.log(compact([0, 1, false, "", 3, "s","e"*23,"a", NaN]));
计算数组中值的出现次数
使用Array.reduce()在每次遇到数组中的特定值时递增计数器
const coumt=(arr,value)=>arr.reduce((a,v)=>v===value?a+1:a+0,0); console.log(coumt([12, 1, 1, 2, 3, 4, 32, 2, 1, 1, 1, 1, 1], 1));若是不理解逗号后面的值,能够再MDN查询
reduce
深度拼合数组
const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v)); console.log(deepFlatten([1, [2], [[3], 4], "a"]));
合理的title,description,keywords:搜索对着三项的权重逐个减少,
语义化的HTML代码
重要内容HTML代码放在最前
重要内容不要用js输出
少用iframe
非修饰性图片必须加alt
提升网站速度
在线的状况,会请求html的manifest属性,它会请求manifest文件的内容,根据内容进行离线存储,让加载页面时,会对新的manifest文件内容进行比较,进行存储
离线的状况,直接使用离线存储的资源
缺点:
更新的资源,须要二次刷新才会被页面采用
不支持增量更新,只有manifest发生变化,全部资源所有从新下载一次
缺少足够容错机制,当清单中任意资源文件出现加载异常,都会致使整个manifest策略运行异常
基本类型:
Boolean Null Undefined string number Symbol(E6)
对象类型: Object
- 数据封装类对象:
Object, Array ,Boolean, Number ,String
- 其余对象:
Function, Arguments ,Math, Date, RegExp,Error
- 任何非基本类型的都是对象类型
区别
基本类型
- 不可变,没法添加删除属性;按值比较,按值传递
对象类型
- 可变,支持添加删除属性,按引用比较,按引用传递
检测对象类型?或者检测一个数据是数组类型
Object.prototype.toString.call([])
typeof只在基本类型的检查上面才好使,在引用类型(Function除外) 里面他返回的都是object
感受我会写好多东西呀,能够当作复习哦,面试的时候说个一二十分钟不是问题
$.ajax({//jQuery url:"http://www.baidu.com",//请求的url地址 dataType:"json",//返回的数据格式 data:{} //参数 type:"GET" success:function(data){ //请求成功的请求 } })
// 1.建立 var ajax = new XMLHttpRequest(); // 2设置 ajax.open('get', 'Ajax_get.php'); // 3.发送 ajax.send(null); // 4.状态事件 ajax.onreadystatechange = function() { if (ajax.readyState == 4 && ajax.status == 200) { // 5.使用返回的数据 修改页面的内容 // responseText 返回的就是一个 字符串 // 咱们 在ajax 中 若是 是经过 ajax.responseText 获取到的 通通都是字符串 console.log(ajax.responseText); } }
var ajax = new XMLHttpRequest(); // 使用post请求 ajax.open('post','ajax_post.php'); // 若是 使用post发送数据 必须 设置 以下内容 // 修改了 发送给 服务器的 请求报文的 内容 // 若是须要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。而后在 send() 方法中规定您但愿发送的数据: ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 发送 // post请求 发送的数据 写在 send方法中 // 格式 name=jack&age=18 字符串的格式 ajax.send('name=jack&age=998'); // 注册事件 ajax.onreadystatechange = function () { if (ajax.readyState==4&&ajax.status==200) { console.log(ajax.responseText); } }
function getXhr() { var xhr = null; if (window.XHLHttpRequest) { xhr = new XMLHttpRequest(); } else { xhr = new ActiveXObect("Microsoft.XMLHttp"); } return xhr; }
这个为何我会单独写出来建立的对象兼容由于这里涉及到:
js高阶编程技巧之"惰性思想":可以执行一次就搞定的绝对不会执行屡次
Ajax:asyncjavascript and xml 异步的js和XML
客户端js中的方法,用来向服务器端发送请求(还能够传递给服务器端数据,而后把服务器端返回的内容获取
xml:可扩展的标记语言(在xml文件使用的标签都是本身扩展的)
利用本身扩展的有规则的标记来存储相关的数据(xml后台用处很大)
xhr.readyState:请求状态码
0 (未初始化)当前的请求尚未发送
1 (载入)url地址已经打开(发送前的参数配置已经完成)
2(载入完成) 响应头信息已经接收
3(交互) 主要返回的内容正在服务器端进行准备处理
4(完成) 响应主体的内容已经成功返回到客户端
xhr.status:HTTP网络状态码,描述了服务器响应内容的状态
200 表示响应主体的内容已经成功返回了
301->永久重定向/永久转移
302->临时重定向/临时转移 服务器的负载均衡 304 本次获取的内容是读取缓存中的数据 400 客户端传递给服务器端的参数出现错误 401 无权限访问 404 客户端访问的地址不存在 500 未知的服务器错误 501->服务器已经超负荷 一台服务器能承受10000人,那么第10001我的访问,若是没有作服务器的负载均衡,那么这我的的状态码就是503
GET和POST的区别
get是从服务器获取数据----"取";post是向服务器提交数据---"发"
大小问题
GET请求传递给服务器的内容存在大小限制,而POST理论上没有限制
缘由:GET经过URL传参给服务器,HTTP协议没有对URL长度进行限制,可是每一个浏览器对于URL的长度存在限制,谷歌8k,火狐7kb,IE2kb,若是URL的长度超过限制,浏览器会把超出的部分截取
缓存的问题
GET请求会出现缓存(这个缓存不必定是304),POST是没有缓存的
在项目中咱们的GET请求通常不会让其出现缓存"清除缓存":在URL的末尾追加一个随机数
xhr.open("get","/getList?num=12&="+Math.random()")
if (ajax["type"].toLowerCase() === "get") { //->GET请求还须要在URL的末尾追加随机数 var suffix = ajax["url"].indexOf("?") > -1 ? "&" : "?"; ajax["url"] += suffix + "_=" + Math.random(); }安全问题
- 通常来讲GET不安全,可是POST相对安全些
var xhr=new XMLHttpRequest(); xhr.open("get", "./vue.html"); xhr.send(null); xhr.onreadystatechange=function () { console.log(xhr.readyState);//没有任何输出 //输出的2,3,4由于在存储的时候就已经把0,1已经执行了,也就是说在前面就已经把0,1都已经执行了 }
js的垃圾回收机制是为了以防止内存泄露,内存泄露的含义就是当已经不须要某块内存是这块内存还存在着,垃圾回收机制就是间歇的不按期的寻找不在使用的变量,并释放掉它们所指向的内存
变量的生命周期
回收方式:标记清除.引用技术(不经常使用)
标记清除
引用技术
引用技术的含义就是跟踪记录每一个值被引用的次数
什么是跨域
只要协议,域名,端口有任何一个不一样,就是跨域
为何不能跨域
浏览器的同源策略,用来保护用户的安全
跨域的解决方案
JSONP
浏览器能够引用不一样域下的JS文件,利用这个特性,实现跨域
get请求
callback参数
document.domain
页面地址是
http://a.baidu.com
,嵌入的iframe是http://b.baidu.com/
分别始终hi页面和iframe的
document.domain
为:baidu.com就能够解决
CORS方案
CORS定义一种跨域访问的机制,可让AJAX实现跨域访问,CORS容许一个域
向另外一个域提交跨域的ajax请求
header("Access-Control-Allow-Origin","*")
post请求
反向代理
正向代理代理的对象是客户端,
反向代理代理的对象是服务器
使用HTML5引进的window.postMessage
方法来跨域
我的认为
window.name
的方法既不复杂也能兼容全部的浏览器
HTTP:相对HTTPS来讲,速度较快且开销较小,默认是80端口
HTTPS相对安全但开销较大(数据以加密的形式传递),默认端口443
HTTP是明文跑到TCP上,而HTTPS跑在SSL/TLS应用层之下,TCP上
HTTPS
var count = 0; console.log(typeof count === "number"); // true , 这个不用解释了 console.log(!!typeof count === "number"); // false // 这里涉及到就是优先级和布尔值的问题 // typeof count 就是字符串"number" // !!是转为布尔值(三目运算符的变种),非空字符串布尔值为 true // 最后才=== 比较 , true === "number" , return false
(function(){ var a=b=3; //var a,a=b; b=3跑到全局去了 })()
null instanceof Object //false 两个都不熟悉一个数据类型
var val = 'smtg'; console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing'); //+的优先级大于等于号
slice()
根据索引值和索引值截取字符串(若截取数组,不改变原数组)
slice(1,2) //从第0项开始,包左不包右
slice(-3) //从后往前截取到倒数第三个
slice(5,2)/返回空字符
splice() 截取数组,不能截取字符串
splice(1,2) //改变原数组 ,从0项开始删除
1,2项
splice(1,2,"aaa","bbb") //替换
1,2的值
splice(1,0,"aaa","bbb") //在键值对为1的前面插入
两个值 ,第二个参数为0就是不替换参数,1就是替换一个参数
函数声明的时候,会生成一个独立的做用域
同一做用域的对象能够互相独立访问
做用域呈现包含状态,造成做用域链,子做用域的对象能够访问父做用域的对象,反之不能;
另外子做用域会使用最近的父做用域的对象
闭包是函数
做为内部函数保存着对外部函数中变量的引用
加载一个资源的过程
浏览器渲染页面的过程
高复用低耦合,这样文件小,好维护,并且好扩展
是把本来须要绑定的事件委托给父亲,让父元素担当事件监听的职务
简单的说就是某个时间原本该本身干的,可是本身不干,交给别人来干,就交
<ul id="ul1"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> </ul> 实现功能是点击li,弹出123: 复制代码 window.onload = function(){ var oUl = document.getElementById("ul1"); var aLi = oUl.getElementsByTagName('li'); for(var i=0;i<aLi.length;i++){ aLi[i].onclick = function(){ alert(123); } } }
优势能够提升性能
DNS域名解析
发起TCP的3次握手
简历TCP链接后发起http请求
服务器端响应http请求,浏览器获得html代码
浏览器解析html代码,并请求html代码中的资源
浏览器对页面进行渲染呈现给用户
发起TCP的3次握手
在客户端和服务器之间创建正常的TCP网络链接是
客户端发送SYN给服务器
服务端返回SYN+ACK给客户端
客户端确认,返回ACK给服务端
.classB{ background-color: red; } .classA{ background-color: rebeccapurple; } </style> <!--与样式定义的先后有关--与标签的class顺序无关--> <p class="classA classB">1111111</p>
页面滚动条问题
web页面在pc浏览时有滚动条,可是在移动端浏览器打开时,没有滚动条
解决方法
给body一个大容器 设置
overflow:auto/scroll
其余的兼容性就不说了,看着脑壳疼,解决方案等遇到了再解决吧
分为8个阶段,建立前/后,载入前/后,更新前/后,销毁前/后
封装.继承,多态
封装
继承
多态
总结
原型链继承(父类的实例做为子类的原型)
构造继承(复制父类的实例属性给子类)
实例继承
拷贝继承
组合继承
寄生组合继承
解决回调问题
最大的好处就是在异步执行的流程中,把执行代码和处理结果的代码清晰的分离
promise有三种状态:等待(pending ). 已完成(fulfilled /f斐o/). 已拒绝(rejected /v jk/)
一个promise的状态之可能从"等待"转到"完成"或者"拒绝",不能逆向转移
promise本质就是一个函数,他能够接受一个函数做为参数,而且会返回promise对象
promise.then(function(value) { // 若是调用了resolve方法,执行此函数 }, function(value) { // 若是调用了reject方法,执行此函数 }); promise.then(function(result) { //成功时的处理 }).catch(function(error) { //错误时的处理 }) resolve /v 肉/
loader是用来编译和处理资源的
loader用于对模块的源代码进行转换,loader可使你在import或"加载"模块是预处理文件,所以,loader相似于其余构建工具中"任务(task)",并提供了处理前端构建步骤的强大方法
当咱们遇到大问题时,首相想到的老是去搜搜看有没有现成的解决方案,但现实却不免是没有解决问题,在这种状况下,咱们也能够尝试去写一些插件,组件,或者一个通用化的解决方案,来解决自身的问题,同时对本身掌握一些知识也会有帮助,并且尝试事后可能发现,他也没这么难
每一个组件都是Vue的实例,每一个组件都应该有本身做用域
函数拥有本身的做用域,能够避免组件共享data属性
路由:直接找到与地址匹配的组件,并将其渲染出来,改变浏览器地址,但不请求服务器
实现方式:地址中添加#来欺骗浏览器,地址的改变是进行页面内导航
vue router是hash值改变,页面内跳转
location.href是页面跳转,页面刷新
Gulp是一种可以优化前端代码的开发流程的工具
webpack是一种模块化的解决方案
plugins并非直接操做单个文件,他直接对整个构建过程起做用
好比他会将入口引用css文件,都打包独立的css文件,而不是内嵌在js打包文件中
obj.call(thisObj,arg1,arg2)
obj.apply(thisObj,[arg1,arg2])
二者做用一致,都是把obj(this)绑定到thisObj
,这时候thisObj
具有了obj的属性和方法
区别是call接受的是连续参数,apply接受的是数组参数
typeof用于判断基本类型,是一元运算符.返回结果是字符串
undefined .boolean .null.string.number.symbol.function.object
instanceof用于判断对象的类型,是二元运算符.返回结果是布尔值
注意:基本类型与一些特殊类型没法获得真的结果
#aaa{ width: 0; height: 0; border:20px solid transparent; border-bottom-color:red; }
AMD:异步模块定义,全部模块异步加载,模块加载不影响后续运行,全部依赖模块的语言必须写在回调函数中,提早执行依赖前置主要应用于require.js 一个当多个用
CMD:同步加载 延迟执行 依赖就近,主要应用sea.js推荐每个模块职责单一
instanceof方法主要检测 变量的constructor是否与Array相等,也就是检测变量的原型链是否指向Array构造函数的prototype原型上
arr instanceof Array
arr.constructor ===Array
Array.isArray()
Object.prototype.toString.call(arr)
javascript是面向对象的,每一个实例对象都有一个
__proto__
属性,该属性指向它原来对象,这个实例对象的构造函数有一个原型属性prototype,与实例的__proto__
属性指向同一个对象,当一个对象在查找一个属性的时,自身没有就会根据__proto__
向它的原型进行查找,若是都没有,则想他的原型的原型继续查找,直到查到Object.prototype.__proto__
为null,这样也就造成原型链
让本身对原生js又多了一点点小小的认识
false==0
true==1
this永远指向函数运行时所在的对象,而不是函数被建立是所在的对象,匿名函数或者不处于任何对象中的函数指向window
若是call .apply.bind ,指定的this是谁,就是谁
普通的函数调用,函数被谁调用,this就是谁