js基础
列举常用的5个字符串操作方法。
var str='hello world'
- str.length
- str.toUpperCase() : 全变为大写
- str.toLowerCase() :全变为小写
- str.indexOf(“world”) : 返回指定子串出现的位置
- str.substring(0,5) : 返回下标从0到5的字串,不含下标5的字符
- str.substring(5) : 返回下标从5到结束的字串
列举常用的数组操作方法。
- length 设置或返回 数组中元素的数目
- push() 向数组的末尾添加一个或多个元素,并返回新的长度,也就是添加元素后的数组长度。
- shift():用于把数组的第一个元素从其中删除,并返回第一个元素的值。
- unshift():向数组的开头添加一个或更多元素,并返回新的长度。
- pop():用于删除并返回数组的最后一个元素。
- splice():用于插入、删除或替换数组的元素。
- concat():方法用于连接两个或多个数组。
- join():用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
- toString():方法可把数组转换为字符串,并返回结果。
- reverse():方法用于颠倒数组中元素的顺序。
- slice():方法可从已有的数组中返回选定的元素。
- sort():方法用于对数组的元素进行排序(从小到大)。
- indexOf():返回获取项在数组中的索引
- lastIndexOf():返回获取项在数组中出现的最后一次索引
- forEach():循环遍历数组 参数是一个匿名函数 默认返回为undefined
- map():循环遍历数组 参数是一个匿名函数
对象
- charAt(): 返回在指定位置的字符。
charCodeAt(): 返回在指定的位置的字符的 Unicode 编码。 - concat():连接字符串。
- indexOf():检索字符串。
- match(): 找到一个或多个正则表达式的匹配。
- replace():替换与正则表达式匹配的子串。
- search(): 检索与正则表达式相匹配的值。
- slice(): 提取字符串的片断,并在新的字符串中返回被提取的部分。
- split(): 把字符串分割为字符串数组。
- toLocaleLowerCase(): 把字符串转换为小写。
- toLocaleUpperCase(): 把字符串转换为大写。
- toLowerCase(): 把字符串转换为小写。
- toUpperCase(): 把字符串转换为大写。
- substr(): 从起始索引号提取字符串中指定数目的字符。
- substring(): 提取字符串中两个指定的索引号之间的字符。
浅拷贝和深拷贝区别,描述或者手写深拷贝。
深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同。
基本数据类型主要是:undefined,boolean,number,string,null 都是分配在栈中的,赋值都是深拷贝的表现(就是你的值改变不影响我)。
引用类型(引用代表了有指针),栈里存指针变量,指针指向堆中存放的值;浅拷贝是拷贝的指针,深拷贝是拷贝的指针和数值。
参考文章
call和apply的用法和区别。
- call() 接收若干个参数的列表
func.call(thisArg,arg1,arg2,....)
- apply() 接收一个包含多个参数的数组
func.call(thisArg, [arg1,arg2,....])
- 两者的作用是一样的
- 实现继承,一个对象的方法或属性,然后让另外一个新的对象来继承它,而不是在这个新的对象中再写一次这个方法或属性
- 改变函数执行的上下文(this),调用别人的方法
简单实例
- call()
function Func1(x,y) {
this.sum = x + y;
}
function Fun2(x,y) {
Func1.call(this, x, y);
}
var a = new Fun2(1,2)
console.log(a.sum) // 3
- apply()
function Func1(x,y) {
this.sum = x + y;
}
function Fun2(x,y) {
Func1.apply(this, [x, y]);
}
var a = new Fun2(1,2)
console.log(a.sum) // 3
参考文章
JS继承的几种方法。
既然要实现继承,那么首先我们得有一个父类
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
1、原型链继承
核心: 将父类的实例作为子类的原型
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
2、构造继承
核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
缺点: 只能解决属性的继承,使用属性的值不重复,但是父级类别的方法不能继承
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
3、实例继承
核心:为父类实例添加新特性,作为子类实例返回
function Cat(name){
var instance = new Animal();
instance.name = name || 'Tom';
return instance;
}
4、拷贝继承
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name || 'Tom';
}
5、组合继承
核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
缺点: 父类的原型对象调用了两次
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
6、寄生组合继承
核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})();
事件冒泡以及事件捕获
这是两个相反的行为
- 事件冒泡:就是从里到外,从子元素(点击的元素)到父元素的事件触发过程
- 时间捕获:就是从外到里,从父元素到子元素(点击元素)的事件出发过程
注意:addEventListener中有三个属性,第三个是布尔值,默认是false为事件冒泡,true为事件捕获
举个应用场景:我们想要在点击每个h5标签时,弹出对应的innerHTML 。常规做法是遍历每个h5,然后在每个h5上绑定一个点击事件,这种做法在h5较少的时候可以使用,但如果有一万个h5,那就会导致性能降低。这时就需要事件代理出场了。
obj1.addEventListener('click',function(e){
var e=e||window.event;
if(e.target.nodeName.toLowerCase()=='h5'){
alert(e.target.innerHTML);
}
},false);
由于事件冒泡机制,点击了h5后会冒泡到div,此时就会触发绑定在div上的点击事件,再利用target找到事件实际发生的元素,就可以达到预期的效果。
- 阻止事件冒泡:event.stopPropagation(),在IE浏览器中使用e.cancleBubble=true,在jQuery中使用return false。