var numbers=[1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4));//3 返回第一个出现的4位置
alert(numbers.lastIndexOf(4));//5 返回最后一个出现的4位置
alert(numbers.indexOf(4,4));//5 从位置4开始查找第一个4出现的位置
alert(numbers.lastIndexOf(4,4));//3 从位置4开始查找最后一个4出现的位置
var person={name:"ToNi"};
var people=[{name:"ToNi"}];
var morePeople=[person];
alert(people.indexOf(person));//返回-1 必须严格相等,不仅仅是值相等
alert(morePeople.indexOf(person));//返回0
var i;
for (i = 0; i < 10; i++) {
(function (i) {
var a = document.createElement('a');
a.innerHTML = i + '<br>';
a.addEventListener('click', function (e) {
e.preventDefault();
alert(i);
});
document.body.appendChild(a);
})(i)
}
实现数组的随机排序
Array.prototype.shuffle = function () {
var input = this;
for (var i = input.length - 1; i >= 0; i--) {
var randomIndex = Math.floor(Math.random() * (i + 1));
var itemAtIndex = input[randomIndex];
input[randomIndex] = input[i];
input[i] = itemAtIndex;
}
return input;
}
var tempArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
tempArray.shuffle();
console.log(tempArray);
function foo() {
var x = 1;
return function () {
alert(x);
}
};
var bar = foo();
bar(); // 1
var x = 2;
bar(); // 1
什么是自由变量
自由变量就是当前作用域没有定义的变量,即“自由变量”
var a = 100;
function F1() {
var b = 200;
function F2() {
var c = 300;
//a是自由变量
console.log(a);
//b是自由变量
console.log(b);
console.log(c);
}
F2();
}
F1();
function formatDate(dt) {
if (!dt) {
dt = new Date();
}
var year = dt.getFullYear();
var month = dt.getMonth() + 1;
var date = dt.getDate();
if (month < 10) {
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
return year + "-" + month + "-" + date;
}
var dt = new Date();
var formatDate = formatDate(dt);
console.log(formatDate);
获取随机数,要求是长度一致的字符串
var random = (Math.random() * 10 + "0000000000").slice(0, 10);
console.log(random);
写一个能遍历对象和数组的通用forEach函数
function forEach(obj, fn) {
if (obj instanceof Array) {
//准确判断是不是数组
obj.forEach(function (item, index) {
fn(index, item);
})
} else {
//不是数组就是对象
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
fn(key, obj[key]);
}
}
}
}
//检测数组
var arr = [1, 2, 3];
//这里顺序换了,为了和对象的遍历格式一致
forEach(arr, function (index, item) {
console.log(index, item);
});
//检测对象
var obj = {
x: 100,
y: 200
};
forEach(obj, function (key, value) {
console.log(key, value);
})
JavaScript中数组操作常用方法
// 2、获取对象的类型,比较是否为object类型(此方法只能检测是否为Object,不推荐) if(typeof(value)=="Object") { //对数组执行某些操作 }
// 3、检测对象是否为数组,使用Array.isArray()方法 // (只支持ie9+,firefox 4+,safari 5+,opera 10.5+和chrome) if(Array.isArray(value)) { //对数组执行某些操作 }
count=colors.push("black");//推入另一项 alert(count);//3
var item=colors.pop();//移除最后一项,并返回最后一项的值 alert(item);//“black” alert(colors.length);//2
// 以上代码首先我们使用push()将两个字符串推入数组的末尾,并将返回的结果保存在变量count中。 // 然后再推入一个值,而结果任然保存在count中.因为此时数组中包含3项,所以push()返回3。 // 在调用pop()时,它会返回数组的最后一项,即字符串"black".此后,数组中仅剩两项。
function compare(value1, value2) { return value1 - value2; } var values = [0,1,5,10,15]; values.sort(compare); console.log(values); //0,1,5,10,15
var numbers=[1,2,3,4,5,4,3,2,1]; alert(numbers.indexOf(4));//3 返回第一个出现的4位置 alert(numbers.lastIndexOf(4));//5 返回最后一个出现的4位置 alert(numbers.indexOf(4,4));//5 从位置4开始查找第一个4出现的位置 alert(numbers.lastIndexOf(4,4));//3 从位置4开始查找最后一个4出现的位置 var person={name:"ToNi"}; var people=[{name:"ToNi"}]; var morePeople=[person]; alert(people.indexOf(person));//返回-1 必须严格相等,不仅仅是值相等 alert(morePeople.indexOf(person));//返回0
(2)dom.currentStyle.width/height(只有IE浏览器支持,输出值带单位)
(3)window.getComputedStyle(dom).width/height(兼容性好,输出值带单位)
(4)dom.getBoundingClientRect().width/height(兼容性好,输出值不带单位)
DOM事件的级别
(1)DOM0: element.onclick = function(){} (2)DOM2: element.addEventListener('click',function(){},false) 【拓展】 所谓的0级dom与2级dom事件就是不同版本间的差异,具体的说就是,对于不同的dom级别,如何定义事件处理,以及使用时有什么不同。 比如在dom0级事件处理中,后定义的事件会覆盖前面的,但是dom2级事件处理中,对一个按钮点击的时间处理就没有被覆盖掉。 (3)DOM3: element.addEventListener('keyup',function(){},false) (4)建议结合红宝书第6页
DOM事件模型
(1)冒泡型事件处理模型(Bubbling): 冒泡型事件处理模型在事件发生时,首先在最精确的元素上触发,然后向上传播,直到根节点,反映到DOM树上就是事件从叶子节点传播到根节点。 (2)捕获型事件处理模型(Captrue): 相反地,捕获型在事件发生时首先在最顶级的元素上触发,传播到最低级的元素上,在DOM树上的表现就是由根节点传播到叶子节点。 【捕获事件的具体流程】 window==>document==>html==>body==>父级元素==>目标元素 (3)标准的事件处理模型分为三个阶段:
Event对象的常见应用
(1)event.preventDefault(): 阻止事件的默认行为 (2)event.stopPropagation(): 阻止事件的进一步传播,也就是阻止冒泡 (3)event.stopImmediatePropagation(): 阻止剩余的事件处理函数的执行,并防止当前事件在DOM树上冒泡。 (4)event.currentTarget: 返回绑定事件的元素 (5)event.target: 返回触发事件的元素
JavaScript自定义事件
JavaScript类的声明
JavaScript类之间的继承
(1)借助构造函数实现不完全继承,无法继承方法:
(2)借助原型链实现继承,所有的属性和方法都得去原型链上去找,因而找到的属性方法都是同一个,所以直接利用原型链继承是不现实的。
(3)组合方式实现继承
(4)组合继承的优化1
(5)组合继承的优化2(俗称寄生式继承)
创建对象有几种方法
(1)字面量:
(2)通过构造函数
(3)通过Object.create
什么是原型和原型链?有什么特点
(1)每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象不存在这个属性,那么就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。 (2)特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 内建对象。 (3)更多原型知识1
JavaScript的运行机制
(1)JavaScript是单线程,一个时间段内,JavaScript只能干一件事情。任务队列分为同步任务和异步任务。 (2)异步任务类型:setTimeout和setInterval、DOM事件、ES6中的Promise
JavaScript异步加载的方式
(1)动态脚本加载; (2)defer (3)async
JavaScript的typeof返回哪些数据类型?
Object number function boolean underfind、String; 【拓展】 比较混淆的是:介绍JavaScript的基本数据类型 答案为:Undefined、Null、Boolean、Number、String、Symbol(创建后独一无二且不可变的数据类型
JavaScript中的事件委托是什么
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
为什么要使用JavaScript的事件委托
为了减少代码的DOM操作,提高程序性能。更多详情
JavaScript中的闭包
(1)有权访问另一个函数作用域内变量的函数都是闭包。 (2)闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会徒增内存消耗!另外使用闭包也要注意变量的值是否符合你的要求,因为他就像一个静态私有变量一样。 (3)更多
window.onload和DOMContentLoaded的区别是
用JavaScript创建10个标签,点击的时候弹出来对应的序号
实现数组的随机排序
JavaScript中有哪些内置函数,与内置对象的区别是什么
(1)内置函数: 是浏览器内核自带的,不用任何函数库引入就可以直接使用的函数,如常规函数(alert等)、数组函数(reverse等)、日期函数(getDate等)、数学函数(floor等)、字符串函数(length等); (2)内置对象: 是浏览器本身自带的,内置对象中往往包含了内置函数。内置对象有Object、Array、Boolean、Number、String、Function、Date、RegExp等。
JavaScript变量按照存储方式区分为哪些类型,并描述其特点
如何理解JSON
其实JSON只不过是一个JavaScript对象而已。stringify()是把对象变成字符串;parse()是把字符串变成对象。
JavaScript中&&和||
(1)只要“||”前面为false,不管“||”后面是true还是false,都返回“||”后面的值; (2)只要“||”前面为true,不管“||”后面是true还是false,都返回“||”前面的值。 (3)且在js逻辑运算中,0、”“、null、false、undefined、NaN都会判为false,其他都为true。 (4)只要“&&”前面是false,无论“&&”后面是true还是false,结果都将返“&&”前面的值; (5)只要“&&”前面是true,无论“&&”后面是true还是false,结果都将返“&&”后面的值。
描述new一个对象的过程
(1)创建空对象:var obj = {}; (2)设置新对象的constructor属性为构造函数的名称,设置新对象的proto属性指向构造函数的prototype对象:obj.proto = ClassA.prototype; (3)使用新对象调用函数,函数中的this被指向新实例对象:ClassA.call(obj); //{}.构造函数();
(4)将初始化完毕的新对象地址,保存到等号左边的变量中 【注意】 若构造函数中返回this或返回值是基本类型(number、string、boolean、null、undefined)的值,则返回新实例对象;若返回值是引用类型的值,则实际返回值为这个引用类型。
什么是构造函数
(1)构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象。 (2)注意事项:
函数声明和函数表达式的区别
说一下对变量提升的理解
(1)顾名思义,就是把下面的东西提到上面。在JS中,就是把定义在后面的东东(变量或函数)提升到前面中定义。
(2)根据上面变量提升原件以及js的作用域(块级作用域)的分析,得知 上面代码真正变成如下:
(3)在我们写js code 的时候,我们有2中写法,一种是函数表达式,另外一种是函数声明方式。我们需要重点注意的是,只有函数声明形式才能被提升。
说一下this几种不同的使用场景
(1)作为构造函数执行,如果函数创建的目的是使用new来调用,并产生一个对象,那么此函数被称为构造器函数;
(2)作为对象属性执行,对象成员方法中的this是对象本身,此时跟其他语言是一致的,但是也有差异,JavaScript中的this到对象的绑定发生在函数调用的时候;
(3)作为普通函数执行,以普通方式定义的函数中的this:会被自动绑定到全局对象;
(4)对象方法中闭包函数的this
(5)apply函数的参数this,apply方法允许我们选择一个this值作为第一个参数传递,第二个参数是一个数组,表明可以传递多个参数。
如何理解JavaScript作用域
函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。
什么是自由变量
自由变量就是当前作用域没有定义的变量,即“自由变量”
this的特点
this要在执行时才能确认值,定义时无法确认。
同步和异步的区别是什么?分别举一个同步和异步的例
同步会阻塞代码执行,而异步不会;alert是同步,setTimeout是异步。
一个关于setTimeout的笔试题
何时需要异步
在可能发生等待的情况、等待过程中不能像alert一样阻塞程序运行、因此所有的等待的情况都需要异步
JavaScript中的异步和单线程
(1)其实,单线程和异步确实不能同时成为一个语言的特性。js选择了成为单线程的语言,所以它本身不可能是异步的,但js的宿主环境(比如浏览器,Node)是多线程的,宿主环境通过某种方式(事件驱动,下文会讲)使得js具备了异步的属性。 (2)js是单线程语言,浏览器只分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务,这些任务形成一个任务队列排队等候执行,但前端的某些任务是非常耗时的,比如网络请求,定时器和事件监听,如果让他们和别的任务一样,都老老实实的排队等待执行的话,执行效率会非常的低,甚至导致页面的假死。所以,浏览器为这些耗时任务开辟了另外的线程,主要包括http请求线程,浏览器定时触发器,浏览器事件触发线程,这些任务是异步的。
使用JavaScript获取当天的日期
获取随机数,要求是长度一致的字符串
写一个能遍历对象和数组的通用forEach函数
DOM操作的常用API有哪些
获取DOM节点,以及节点的property和Attribute;获取父节点和子节点;新增节点和删除节点
DOM节点的attr和property有何区别
property只是一个JavaScript对象的属性的修改;Attribute是对html标签属性的修改
DOM的本质
浏览器把拿到的HTML代码,结构化一个浏览器能识别并且js可以操作的一个模型而已。
手动编写一个ajax,不依赖第三方库
更多ajax知识,请点击这里
什么是跨域
(1)浏览器有同源策略,不允许ajax访问其他域接口。跨域条件(协议、域名、端口)有一个不同就算是跨域。 (2)可以跨域的三个标签(
<img src=xxx>、<link href=xxx>、<script src=xxx>
)。三个标签的应用场景(<img>
用于打点统计,统计网站可能是其他域、 Githubissues.