目录
js的基本类型有哪些?引用类型有哪些?
如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)
JS常见的dom操作api
解释一下事件冒泡和事件捕获,如何阻止冒泡?如何阻止默认事件?
事件委托(手写例子)
对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?
this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?
call,apply,bind
显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链
创建对象的多种方式
实现继承的多种方式和优缺点
new 一个对象具体做了什么
手写Ajax,XMLHttpRequest
变量提升
举例说明一个匿名函数的典型用例
document load和document DOMContentLoaded两个事件的区别
typeof能够得到哪些值
函数的作用域是什么?js 的作用域有几种?
JS如何实现重载和多态
原生事件绑定(跨浏览器),dom0和dom2的区别?
基本类型:Undefined(声明没有初始化)、Null(没有声明,不存在)、String、Number、Boolean (变量存放在栈区)
引用类型:object、Array、RegExp(正则表达式)、Date、Function、特殊的基本包装类型(String、Number、Boolean)以及单体内置对象(Global、Math)。(同时保存在栈内存和堆内存)
区别联系:引用类型可以添加属性和方法; 在复制变量值时,基本类型会在变量对象上创建一个新值,再复制给新变量。此后,两个变量的任何操作都不会影响到对方;而引用类型是将存储在变量对象的值复制一份给新变量,但是两个变量的值都指向存储在堆中的一个对象,也就是说,其实他们引用了同一个对象,改变其中一个变量就会影响到另一个变量。
typeof可以判断 number string boolean undefined,对于[ ]、null、{ }输出都为object,所以要判断array不能使用typeof;
Object.prototype.toString.call 这是object原生原型的一个扩展函数,可以精确对象类型例如Object.prototype.toString.call('[ ]')输出就是[object Array]; Object.prototype.toString.call('{ }')输出是[object Object]
constructor也可以判断数据类型,[].constructor输出就是Array
节点查找:document.getElementById(根据id查找元素,大小写敏感) 、document.getElementsByTagName (根据标签查找元素,*表示查询所有标签,返回一个HTMLCollection)、document.getElementsByName(根据元素的name属性查找)、document.getElementsByClassName(根据类名查找)、document.querySelector(返回单个Node,如果匹配到多个结果,返回第一个)、document.querySelectorAll(返回一个NodeList) 、document.forms(获取当前页面所有的form)等
节点创建: createElement (通过 createElement 创建的元素并不属于 document 对象,它只是创建出来,并未添加到html文档中,要调用 appendChild 或 insertBefore 等方法将其添加到HTML文档中)、 createTextNode 、 cloneNode(接收一个bool参数,用来表示是否复制子元素) 和 createDocumentFragment (创建一个 DocumentFragment ,也就是文档碎片,它表示一种轻量级的文档,主要是用来存储临时节点,大量操作DOM时用它可以大大提升性能)
节点修改:appendChild 、insertBefore 、removeChild 、replaceChild
节点关系:parentNode 、children 、childNodes 、firstChild 、lastChild 、previousSibling、nextSibling 、 nextElementSibling
元素属性:setAttribute、getAttribute
元素样式:window.getComputedStyle(通过 element.sytle.xxx 只能获取到内联样式,借助 window.getComputedStyle 可以获取应用到元素上的所有样式,IE8或更低版本不支持此方法。)、getBoundingClientRect(用来返回元素的大小以及相对于浏览器可视窗口的位置)
事件冒泡:从事件的目标开始往上冒泡,直到页面的最上一级标签;通俗来讲就是,就是当设定了多个div的嵌套时;即建立了父子关系,当父div与子div共同加入了onclick事件时,当触发了子div的onclick事件后,子div进行相应的js操作,但是父div的onclick事件同样会被触发。 可以通过event.stopPropagation();方法阻止时间冒泡。
事件捕获:从最上一级开始往下查找,直到捕获到事件目标
程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。例:
ele.addEventListener('click',doSomething2,true) //true=捕获 false=冒泡
事件委托:利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
优点:在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;
例:
- 111
- 222
- 333
- 444
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}
闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在;
在函数内部定义一个函数就会产生闭包。
闭包的最大用处有两个,一个是读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
作为对象方法调用(this绑定到当前对象)、
作为函数调用(函数可以直接被调用,此时 this 绑定到全局对象;但是正确的设计方式是内部函数的 this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,出现了变量替代的方法,约定俗成,该变量一般被命名为 that)、
作为构造函数调用(构造函数实际上是为了支持面向对象编程,要使用new调用,否则跟普通函数一样)
call()和apply()这两个方法第一个参数都为this指针指向的目标对象,它们的区别是第二个参数开始传参方式不同。
call传参:obj,arg2,arg3
apply传参:obj,[arg2,arg3,…]
bind() 第一个参数为this指针指向的目标对象,bind方法执行后返回的是一个新函数
如果这个三个方法都没有提供第一个参数或参数是this、null、undefined中的一种,那么都将默认第一个参数为Global对象 。
显式原型:prototype 隐式原型:__proto__
在js中万物皆对象,方法(Function)是对象,方法的原型(Function.prototype)是对象,对象具有属性(__proto__)称为隐式原型,对象的隐式原型指向构造该对象的构造函数的显式原型。 方法(Function)是一个特殊的对象,除了和其他对象一样具有__proto__属性以外,它还有一个自己特有的原型属性(prototype),这个属性是一个指针,指向原型对象。原型对象也有一个属性叫constructor,这个属性包含一个指针,指向原构造函数。
用法:创建实例时,将实例中共享的原型放到原型对象中,让所有实例共享这部分的属性;想要修改所有实例继承的属性,修改原型对象中的属性即可;若想修改单个实例中的属性,重写原型中已经存在的属性即可,不会影响其他实例的属性。
原型链:所有对象都是由它的原型对象继承而来,而原型对象自身也是一个对象,他也有自己的原型对象,这样层层上溯形成一个类似链表的结构,就是原型链。通过原型链可以实现继承。
动态原型模式:
function Person(name) {
this.name = name
if(typeof this.say != 'function') {
Person.prototype.say = function(
alert(this.name)
}
}
原型链继承:引用类型的属性被所有实例共享;
借用构造函数:避免了引用类型的属性被所有实例共享;
组合继承:原型链和借用构造函数的技术组合到一块,使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承; 融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。
首先创建了一个空对象,将空对象的proto成员指向原函数对象的prototype成员对象,将F函数this指针替换成当前新对象再调用原函数。
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.onreadtstatechange = function () {
if (xhr.readystate == 4) {
//响应内容解析完成,可以在客户端调用了
if (xhr.status == 200) {
//客户端的请求成功了
alert(xhr.responseText);
}
}
}
xhr.send(null);
变量提升就是把变量提升提到函数的top的地方。但是只是提升变量的声明,并不会把赋值也提升上来。
函数提升是把整个函数都提到前面去。在我们写js code 的时候,我们有两种写法,一种是函数表达式(var foo = function foo(){}),另外一种是函数声明方式(function foo(){})。我们需要重点注意的是,只有函数声明形式才能被提升。
创建闭包
//通过闭包可以 返回局部变量
function box() {
var user = 'Lee';
return function () {//通过匿名函数返回box()局部变量
return user;
};
}
alert(box()());//通过box()()来直接调用匿名函数返回值
var b = box();
指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?
attribute和property的区别
DOMContentLoaded: DOM解析完成即触发此事件,不等待styles, images等资源的加载;
load:依赖的资源也已加载完成; DOMContentLoaded绑定到document,load绑定到window
我们需要给一些元素的事件绑定处理函数。但问题是,如果那个元素还没有加载到页面上,但是绑定事件已经执行完了,是没有效果的。这两个事件大致就是用来避免这样一种情况,将绑定的函数放在这两个事件的回调中,保证能在页面的某些元素加载完毕之后再绑定事件的函数。
DOM文档加载的步骤为
解析HTML结构。
加载外部脚本和样式表文件。
解析并执行脚本代码。
DOM树构建完成。//DOMContentLoaded
加载图片等外部文件。
页面加载完毕。//load
在第4步,会触发DOMContentLoaded
事件。在第6步,触发load
事件。
document.addEventListener("DOMContentLoaded", function() {
// ...代码...
}, false);
window.addEventListener("load", function() {
// ...代码...
}, false);
=== 和 == , [] === [], undefined === undefined,[] == [], undefined == undefined
== 代表相同, ===代表严格相同;进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较, 而===比较时, 如果类型不同,直接就是false.
双等号==:
(1)如果两个值类型相同,再进行三个等号(===)的比较
(2)如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:
1)如果一个是null,一个是undefined,那么相等
2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较
注意[] === [] 、[] == []返回均为false
number string boolean undefined,对于[ ]、null、{ }输出都为object;
什么是“use strict”,好处和坏处
指在函数内声明的所有变量在函数体内始终是可见的,这就意味着变量在声明之前已经可用了。
全局,局部。使用时注意变量声明会提前
重载:一组具有相同名字,不同参数列表的函数/方法。
实现:1.使用argumnets对象的length,判断参数长度
2.typeof等判断
多态:
常用的数组api,字符串api
1. DOM0级事件处理程序(属性绑定,兼容性好)
通过javascript制定事件处理程序的传统方式,将一个函数赋值给一个事件处理程序属性。特点是简单,跨浏览器。
var btn = document.getElementById("btn");
btn.onclick = function(){
alert('cliked');
}
dom0级方法制定的事件处理程序被认为是元素的方法,因此这个时候事件处理程序是在元素的作用域中运行,this指向当前元素。
btn.onclick = null; //删除事件处理程序
2. DOM2级事件处理程序(函数绑定,兼容性不好)
DOM2级规范以一种符合逻辑的方式来标准化DOM事件,IE9,Firefox,Opera,Safari,Chrome全部已经实现了"DOM2级事件"模块的核心部分。IE8是最后一个仍然使用其专有事件系统的主要浏览器。
addEventListener() 事件绑定 removeEventListener()事件删除
如果定义了两个dom0级事件,dom0级事件会覆盖;dom2不会覆盖,会依次执行;dom0和dom2可以共存,不互相覆盖,但是dom0之间依然会覆盖。
给定一个元素获取它相对于视图窗口的坐标
如何实现图片滚动懒加载
js 的字符串类型有哪些方法? 正则表达式的函数怎么使用?
深拷贝
编写一个通用的事件监听函数
web端cookie的设置和获取
setTimeout和promise的执行顺序
JavaScript 的事件流模型都有什么?
navigator对象,location和history
js的垃圾回收机制
内存泄漏的原因和场景
DOM事件的绑定的几种方式
DOM事件中target和currentTarget的区别
typeof 和 instanceof 区别,instanceof原理
js动画和css3动画比较
JavaScript 倒计时(setTimeout)
js处理异常
js的设计模式知道那些
轮播图的实现,以及轮播图组件开发,轮播10000张图片过程
websocket的工作原理和机制。
手指点击可以触控的屏幕时,是什么事件? 什么是函数柯里化?以及说一下JS的API有哪些应用到了函数柯里化的实现?(函数柯里化一些了解,以及在函数式编程的应用,- 最后说了一下JS中bind函数和数组的reduce方法用到了函数柯里化。)
JS代码调试-