全栈工程师成神之路--JavaScript

@wanqiuz 2018-06-30 07:20:33发表于 wanqiuz/blog-articles 全栈工程师成神之路

⭐️ 闭包

什么是闭包

闭包是定义在函数内部的函数,闭包使得变量即使脱离了该函数的作用域范围也依然能被访问到。

为什么需要闭包

局部变量无法共享和保存,全局变量会污染,希望有一种长久的机制可以保存变量又不会污染全局。

理解闭包

JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里。
JavaScript中的闭包,无非就是沿着作用域链进行变量解析的过程

闭包的缺点

占用更多内存,容易造成内存泄露。

⭐️ 静态作用域和动态作用域

静态作用域(static scope == Lexical scope 词法作用域)的函数中遇到既不是形参也不是函数内部定义的局部变量的变量时,去函数定义时的环境中查询。JavaScript是静态作用域。
动态作用域(dynamic scope)的函数中遇到既不是形参也不是函数内部定义的局部变量的变量时,到函数调用时的环境中查。

JavaScript中this

ES5中函数中的this是由调用时的形参决定的,与静态作用域或者动态作用域无关。

func(p1, p2) ;
obj.child.method(p1, p2);
func.call(context, p1, p2); // 先不讲 apply

前两种都是语法糖,第三种才是正常调用形式:

func(p1, p2); 
// 等价于
func.call(undefined, p1, p2);

但是浏览器里有一条规则:

如果你传的 context 是 null 或者 undefined。
非严格模式下,默认的 context是window 对象;
严格模式下,默认的 context 是 undefined。

ES6中箭头函数式因为不接受this传入,所以this既不是形参也不是函数内部定义的局部变量,就是运用JavaScript静态作用域规则在函数定义时的环境中查找。

⭐️ let与var的区别?

let 为 ES6 新添加申明变量的命令,它类似于 var,但是有以下不同:

  • var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象,var允许重复声明
  • let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升,let 不允许重复声明

⭐️ 跨域

跨域是由浏览器的同源策略引起的
同源指的是协议、域名、端口都相同

  1. JSONP跨域
    原理:Web 页面上调用 js 文件不受浏览器同源策略的影响,所以通过 Script 便签可以进行跨域的请求。
    兼容所有浏览器,但是只能处理GET请求。

  2. CORS(Cross-origin resource sharing)
    CORS(”跨域资源共享")需要浏览器和服务器同时支持才可以生效,对于开发者来说,CORS 通信与同源的 ajax 通信没有差别,代码完全一样。浏览器一旦发现 ajax 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
    因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。
    支持ie10+,以及其它现代浏览器,支持所有请求方式。
    Access-Control-Allow-Origin: * | 访问域名;
    Access-Control-Allow-Methods: GET | POST | PUT | DELETE;

  3. Server Proxy:
    服务器代理,顾名思义,当你需要有跨域的请求操作时发送请求给后端,让后端帮你代为请求,然后最后将获取的结果发送给你。

⭐️ 创建对象的三种方法

第一种方式,字面量

var o1 = {name: "o1"}

第二种方式,通过构造函数

var o2 = new Object({name: "o2"})
var M = function(name){ this.name = name }
var o3 = new M("o3")

第三种方式,Object.create

var  p = {name: "p"}
var o4 = Object.create(p)

新创建的对o4的原型就是p,同时o4也拥有了属性name.

⭐️ 说说HTML5中有趣的标签(新标签及语义化)

如果代码写的语义化,有利于SEO。搜索引擎就会很容易的读懂该网页要表达的意思。例如文本模块要有大标题,合理利用h1-h6,列表形式的代码使用ul或ol,重要的文字使用strong等等。总之就是要充分利用各种HTML标签完成他们本职的工作

⭐️ 当new Foo()时发生了什么

1.创建了一个新对象
2.将新创建的空对象的隐式原型指向其构造函数的显示原型。
3.将this指向这个新对象
4. 执行函数体
5.如果无返回值或者返回一个非对象值,则将新对象返回;如果返回值是一个新对象的话那么直接直接返回该对象。

⭐️ 浏览器渲染原理

1.HTML被解析成DOM Tree,CSS被解析成CSS Rule Tree
2.把DOM Tree和CSS Rule Tree经过整合生成Render Tree(布局阶段)
3.元素按照算出来的规则,把元素放到它该出现的位置,通过显卡画到屏幕上

⭐️ 原型链

凡是对象就有原型,原型也是对象,那么它也有原型,如此下去,就形成了原型链

⭐️ DOM事件类

DOM事件的级别:
DOM0,element.onclick = function(){}
DOM2,element.addEventListener(‘click’, function(){}, false);
DOM事件模型是什么:指的是冒泡和捕获
DOM事件流是什么:捕获阶段 -> 目标阶段 -> 冒泡阶段
描述DOM事件捕获的具体流程
window –> document –> documentElement(html标签) –> body –> …. –> 目标对象
Event对象常见应用:
event.preventDefault(),阻止默认行为
event.stopPropagation(),阻止事件冒泡
event.stopImmediatePropagation(),阻止剩余的事件处理函数执行并且防止事件冒泡到DOM树上,这个方法不接受任何参数。
event.currentTarget,返回绑定事件的元素
event.target,返回触发事件的元素

⭐️ 判断一个变量是否是数组

var a = []; 
// 1.基于instanceof 
a instanceof Array; 
// 2.基于constructor 
a.constructor === Array; 
// 3.基于Object.prototype.isPrototypeOf 
Array.prototype.isPrototypeOf(a); 
// 4.基于getPrototypeOf 
Object.getPrototypeOf(a) === Array.prototype; 
// 5.基于Object.prototype.toString 
Object.prototype.toString.apply(a) === '[object Array]';
// 6.Array.isArray
Array.isArray([]); // true

⭐️ 介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的?

  • 标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin
  • 低版本IE盒子模型:宽度=内容宽度(content+border+padding)+ margin

⭐️ box-sizing属性?

用来控制元素的盒子模型的解析模式,默认为content-box

  • context-box:W3C的标准盒子模型,设置元素的 height/width 属性指的是content部分的高/宽
  • border-box:IE传统盒子模型。设置元素的height/width属性指的是border + padding + content部分的高/宽

⭐️ CSS和HTML的结合方式有3种:

  • 行内样式:在某个特定的标签里采用style属性。范围只针对此标签。
  • 内嵌样式表:在页面的head里采用<style>标签。范围针对此页面。
  • 引入外部样式表css文件的方式。这种方式又分为两种:
    1、采用标签。例如:
    2、采用import,必须写在<style>标签中,并且必须是第一句。例如:@import url(a.css) ;

⭐️ CSS的四种基本选择器

  • 标签选择器:针对一类标签
  • ID选择器:针对某一个特定的标签使用(规定用#来定义)
  • 类选择器:针对你想要的所有标签使用(规定用圆点.来定义)
  • 通用选择器(通配符):针对所有的标签都适用(不建议使用)(通配符*定义)

⭐️ 高级选择器

  • 下一个兄弟选择器:用+隔开
  • 后代选择器:用空格隔开
  • 子代选择器:用符号>表示
  • 交集选择器:用.隔开
  • 并集选择器(分组选择器):用逗号隔开
  • 伪类选择器(伪类:同一个标签,根据其不同的种状态,有不同的样式。这就叫做“伪类”。伪类用冒号来表示。)

⭐️ 伪类选择器分为两种。

(1)静态伪类:只能用于超链接的样式。如下:
:link 超链接点击之前
:visited 链接被访问过之后
PS:以上两种样式,只能用于超链接。
(2)动态伪类:针对所有标签都适用的样式。如下:
:hover “悬停”:鼠标放到标签上的时候
:active “激活”: 鼠标点击标签,但是不松手时。
:focus 是某个标签获得焦点时的样式(比如某个输入框获得焦点)

在css中,这四种状态必须按照固定的顺序写:
a:link 、a:visited 、a:hover 、a:active

⭐️ CSS继承性

关于文字样式的属性,都具有继承性。这些属性包括:color、 text-开头的、line-开头的、font-开头的。
关于盒子、定位、布局的属性,都不能继承。

⭐️ CSS的层叠性

层叠性:就是css处理冲突的能力。 所有的权重计算,没有任何兼容问题!
当多个选择器,选择上了某个元素的时候,要按照如下顺序统计权重:

id的数量,类的数量,标签的数量
因为对于相同方式的样式表,其选择器排序的优先级为:ID选择器 > 类选择器 > 标签选择器(可进位,例如255标签选择器等于1个类选择器)

  • 选择上了,数权重,(id的数量,类的数量,标签的数量)。如果权重一样,谁写在后面听谁的。
  • 没有选择上,通过继承影响的,就近原则,谁描述的近听谁的。如果描述的一样近,比如选择器权重,如果权重再一样重,谁写在后面听谁的。(行级样式 > 内嵌样式表 > 外部样式表(就近原则))

!important标记,此时其权重为无穷大。
附:

  • !important提升的是一个属性,而不是一个选择器
  • !important不影响就近原则

⭐️ class和id的区别

class用于css的,id用于js的。

  • class页面上可以重复。id页面上唯一,不能重复。
  • 一个标签可以有多个class,用空格隔开。但是id只能有id。

⭐️

⭐️

⭐️

⭐️

⭐️

⭐️

⭐️

⭐️

⭐️