详解clientWidth,scrollWidth,offsetWidth,innerWidth的区别
1.innerWidth
对于IE9+、Chrome、Firefox、Opera 以及 Safari:
window.innerHeight=浏览器窗口的内部高度
window.innerWidth=浏览器窗口的内部宽度
1.clientWidth
一、对于 Internet Explorer 8、7、6、5:
document.documentElement.clientHeight表示HTML文档所在窗口的当前高度
document.documentElement.clientWidth表示HTML文档所在窗口的当前宽度
在不同浏览器都实用的 JavaScript 方案:
var w=document.documentElement.clientWidth||document.body.clientWidth;
var h=document.documentElement.clientHeight||document.body.clientHeight;
clientWidth也可以用来获取元素的宽高,不包含元素的border.
clientWidth=元素的width+padding
3.scrollWidth
scrollHeight和scrollWidth,获取网页内容和宽度.
一、针对IE、Opera:(针对整个网页来说)
scrollHeight是网页内容的实际高度,可以小于clientHeight.
二、针对NS、FF:(针对整个网页来说)
scrollHeight也是网页内容的实际高度,但是最小值是clientHeight.
也就是说就算网页内容比浏览器窗口小,但是返回值还是cliengHeight.
浏览器兼容:
var w=document.documentElement.scrollWidth
|| document.body.scrollWidth;
var h=document.documentElement.scrollHeight
|| document.body.scrollHeight;
scrollHeight和scrollWidth还可以获取Dom元素中内容实际占用的高度和宽度.
scrollWidth=元素的width+padding
4.网页尺寸offsetHeight
offsetHeight和offsetWidth,获取网页内容高度和宽度(包括滚动条等边线,会随窗口的显示大小改变)。
offsetHeight=clientHeight+滚动条+边框.(整个网页来说)
浏览器兼容性
var w= document.documentElement.offsetWidth
|| document.body.offsetWidth;
var h= document.documentElement.offsetHeight
offset用来获取DOM元素中内容高度和宽度时包括元素的border.
offsetWidth=元素的width+padding+border
6.23
回调函数
(作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数)
如果一个函数A 作为另一个B的参数那么函数A就被称为回调函数。
解构赋值
ES6新增加的赋值方法,一般分为对象解构和数组结构两种方式。
通过解构赋值可以将属性/值从对象/数组中取出,赋值给其他变量。
作用
交换变量的值
从函数返回多个值
函数参数的定义
提取JSON的值
函数参数的默认值
遍历Map结构
输入模块的指定方法
数组按照顺序解构赋值
// 变量先声明后赋值时的结构
var a, b, rest;
[a, b] = [10, 20]; // a 10; b 20
// 变量声明并赋值时的结构
var [a, b] = [10, 20, 30, 40, 50]; // a 10; b 20
// 默认值
var [a = 12,b] = [,3]; // a 12; b 3
// 将剩余数组赋值给一个变量
var [a, b, ...rest] = [10, 20, 30, 40, 50]; // a 10; b 20; rest [30, 40, 50]
// 注意:如果剩余元素右侧有逗号,会抛出 SyntaxError,因为剩余元素必须是数组的最后一个元素。
var[a,...b,]=[12,23,34,45];
// Uncaught SyntaxError: Rest element must be last element
// 忽略某些返回值
var[a,,b]=[12,23,34,45]; // a 12;b 34
对象按照属性解构赋值
// 变量先声明后赋值时的结构
var a, b, rest;
({a, b} = {a:10, b: 20}); // a 10; b 20
/** 备注:赋值语句周围的圆括号 ( ... ) 在使用对象字面量无声明解构赋值时是必须的。
{a, b} = {a: 1, b: 2} 不是有效的独立语法,因为左边的 {a, b} 被认为是一个块而不是对象字面量。
然而,({a, b} = {a: 1, b: 2}) 是有效的,正如 var {a, b} = {a: 1, b: 2}
你的 ( ... ) 表达式之前需要有一个分号,否则它可能会被当成上一行中的函数执行。
*/
// 变量声明并赋值时的结构
var {a, b} = {a:10, b: 20}; // a 10; b 20
// 给新的变量名赋值
var {a:q, b} = {a:10, b: 20}; // q 10; b 20; a is not defined
// 默认值
var {a = 12, b} = {a:undefined, b: 20}; // a 12; b 3
// 将剩余数组赋值给一个变量
var {a = 10, b, ...rest} = {a:undefined, b: 20, c: 30, d: 40}; // a 10; b 20; rest {c: 30, d: 40}
// 注意:如果剩余元素右侧有逗号,会抛出 SyntaxError,因为剩余元素必须是数组的最后一个元素。
var{a = 10, b, ...rest,} = {a:undefined, b: 20, c: 30, d: 40};
// Uncaught SyntaxError: Rest element must be last element
// 对象属性计算名和解构
let key = "z";
let { [key]: foo } = { z: "bar" }; // foo 'bar';z is not defined
// 解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)
字符串结构
// 当作数组结构
var [q,w] = '12'; // q 1; w 2
// 当作对象结构
var { length}= '12';// length 2
ES6闭包
简单来说:一个作用域可以访问另外一个函数内部的局部变量。闭包指有权访问另一个函数作用域中的变量的函数 简单理解:一个作用域可以访问另外一个函数内部的局部变量
function fn(){
let num = 10
function fun(){
console.log(num)
}
fun()
}
fn() //10
闭包的主要作用:延伸了变量的作用范围。
// fn 外面的作用域可以访问fn 内部的局部变量
function fn(){
let num = 10
// 方法一: 先定义再返回函数
function fun(){
console.log(num)
}
return fun //返回 fun函数
}
let f = fn()
f() //10
闭包就是函数内部的子函数—— 等于没说
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。——靠谱
闭包就是能够读取其他函数内部变量的函数,在本质上是函数内部和函数外部链接的桥梁——靠谱
函数和对其周围状态(词法环境)的引用捆绑在一起构成闭包(closure)——很靠谱
JS 执行栈
当 js 执行全局代码的时候,会编译全局代码并创建全局上下文,全局执行上下文是只有一个的。
当执行函数的时候,会编译函数中的代码,然后创建函数上下文,函数执行完成之后,上下文就会被销毁。
执行 eval 函数的时候,eval会被编译,并创建 eval 上下文。
一.什么是执行栈?
在JavaScript当中函数一旦过多,就有多个函数执行上下文,每次调用函数创建一个新的执行上下文,那如何管理创建的那么多执行上下文呢?
JavaScript 引擎创建了执行上下文栈来管理执行上下文。可以把执行上下文栈认为是一个存储函数调用的栈结构,遵循先进后出的原则。
执行栈: call stack 一种结构,放的是函数的执行环境,每一次函数执行之前,他的所有内容全部会放到执行栈中,函数调用之前,会创建执行环境,放到执行栈当中,函数调用完成,销毁执行环境。
如上图所述:在执行栈中必须遵守先进后出,后进先出,自上而下的顺序。
JavaScript 执行在单线程上,所有的代码都是排队执行。
一开始浏览器执行全局的代码时,首先创建全局的执行上下文,压入执行栈的顶部。
每当进入一个函数的执行就会创建函数的执行上下文,并且把它压入执行栈的顶部。当前函数执行完成后,当前函数的执行上下文出栈,并等待垃圾回收。
浏览器的 JS 执行引擎总是访问栈顶的执行上下文。
执行机制
单线程
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程
于是,JS 中出现了同步和异步。
同步:
前一个任务结束后再执行后一个任务
异步:
在做这件事的同时,你还可以去处理其他事情
同步任务
同步任务都在主线程上执行,形成一个 执行栈
异步任务
JS中的异步是通过回调函数实现的
异步任务有以下三种类型
普通事件,如click,resize等
资源加载,如load,error等
定时器,包括setInterval,setTimeout等
异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)
块级作用域和局部作用域的区别
1.在块级作用域中,通过var定义的变量是全局变量;
2.在局部作用域中,通过var定义的变量是局部变量;
3.无论是在块级作用域还是局部作用域,只要省略了变量前面的let或者var,变量就会变成全局作用域里面的变量。
JS中三种创建对象的方式
利用字面量创建对象
利用new Object创建对象
利用构造函数创建对象