1.相对定位,绝对定位,固定今晚,粘滞定位,静态定位有什么区别?
脱离文档流的有:绝对定位,固定定位,粘滞定位。
没有定位属性与效果:静态定位。
参考点不同:
相对定位:相对于原先自己的定位。
绝对定位:相对具有定位元素的上层元素。
固定定位:相对于浏览器窗口定位
粘滞定位:相对定位+固定定位,有临界值。(表现为在跨越临界值之前是相对定位,之后为固定定位)。
2.什么是块元素,块元素有哪些特点?
块元素常用于搭建页面框架,常见的块元素有:div,h1~h6,p,ul>li,ol>li等
特点:独占一行空间,高度由内容决定,可以指定宽高,块元素内允许嵌套其他块元素与行内元素。
3.如何使用css绘制一个三角形?
不给盒子元素设置宽高,给四个方向分别设置边框,但是颜色都为透明,设置其中一个方向边框色,例如border-bottom,
那么将绘制一个三角朝上的三角形。
#app { width: 0;
height: 0;
border: 100px solid transparent;
border-bottom: 100px solid #ccc;
}
4.js数组中哪些方法实在原值上进行修改?哪些方法没有对原值进行修改?
改变原数组:
push() 可接受任意类型的参数,将它们逐个添加到数组的末尾,并返回数组的长度
pop() 移除数组中的最后一个项目并返回该项,同时将数组的长度减一
shift() 移除数组中的第一项并返回该项,同时将数组的长度减一
unshift() 在数组的前端添加任意个数,并返回数组的长度
splice() 接受3个参数(start_index,length,替换或者追加的元素),返回选中的元素
sort() 可以用来为数组排序,可以传入一个比较的函数(函数作为参考)
reverse()
不改变原数组:
concat() 数组的拼接,先创建当前数组的一个副本,然后将接受到的参数添加到这个副本的末尾
slice() 接收连个参数(start_index,end_index),返回该截取返回的元素
every() 数组的迭代方法,全部成员都满足才返回true
some() 数组的迭代方法,只要有一个成员满足就会返回true
filter() 数组的迭代方法,返回满足条件的元素
map() 数组的迭代方法,有返回值
forEach() 数组的迭代方法,无返回值
5.在js中如何判断一个数据类型?
可以通过typeof来判断基本数据类型以及对象,函数
通过Array.isArray()来判断引用数据类型是对象还是数组
通过instanceof来判断对象是否是某个构造函数的实例对象
通过Object.prototype.isPrototypeOf(对象)来判断对象是都是某个原型链中的后代
6.在js的面向对象中继承方式有哪几种,分别进行描述。
原型链继承
function Animal(){}
Animal.prototype.name = "xiaobai";
Animal.prototype.age = 2;
Animal.prototype.sayName = function(){
console.log(this.name);
}
function Dog(){}
Dog.prototype = new Animal();//完成了一个原型链的继承操作
Dog.prototype.constructor = Dog;//需要重新指定构造函数
var d1 = new Dog();
console.log(d1);
console.log(d1.name);
d1.sayName();
每个构造函数都有一个原型对象,原型对象中都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。当原型对象等于另外一个类型的实例即继承。
如果某一个构造函数实例对象修改了原型对象上的属性值和方法,则也会影响其他实例对象。
经典继承(伪继承)
function Animal(name,age){
this.name = name;
this.age = age;
}
function Dog(name,age,color){
Animal.call(this,name,age);
this.color = color;
}
var d1 = new Dog('xiaobai',2,'white');
console.log(d1);
伪造对象 或 借用构造函数,在子类型构造函数的内部调用超类型构造函数。
函数不过是在特定环境中执行代码的对象,因此通过apply(),call()方法可以在(将来)新建对象上执行构造函数,即在子类型对象上执行父类型函数中定义的所有对象初始化的代码。
结果每个子类实例中都具有了父类型中的属性以及方法
原型链+构造函数
function Animal(name,age){
this.name = name;
this.age = age;
}
Animal.prototype.sayName= function(){
console.log(this.name);
}
function Dog(name,age,color){
Animal.call(this,name,age);
this.color = color;
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;//将构造函数设置回来
Dog.prototype.sayColor = function(){//子类自己的方法
console.log(this.color);
}
var d1 = new Dog('xiaobai',2,'white');
console.log(d1);
d1.sayName();
d1.sayColor();
原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承
7.简述js构造函数的this指向问题。
this指向实际操作的对象,如果没有操作对象则指代全局的global或者window对象
8.什么是闭包?如何解决闭包带来的内存泄露问题?
闭包是指有权访问另一个函数作用域中的变量的函数,闭包的创建方式,就是在一个函数内部创建另外一个函数。
内存泄露问题:主动释放内存空间,例如
function showId() {
var el = document.getElementById("app")
el.onclick = function(){
aler(el.id)
// 这样会导致闭包引用外层的el,当执行完showId后,el无法释放
}
}
// 改成下面
function showId() {
var el = document.getElementById("app")
var id = el.id
el.onclick = function(){
aler(id)
}
el = null // 主动释放el
}
9.用递归的方法实现1到100求和。
function add(n) {
if(n==0) return 1;
else return n+add(n-1);
}
var result = add(100);
console.log(result);
10.输入一个字符串和一个字母,输出这个字母在这个字符串中出现的次数,例如输入hello,输出2。
第一种方法:
function count(str,char) {
var res = 0;//次数
for(var i=0;i<str.length;i++){
if(str[i]===char)res++;
}
return res;
}
var result = count("hello","l");
console.log(result);
第二种方法:
function count(str,char) {
var pat = new RegExp(char,'gm');
var res = str.match(pat);
return res.length;
}
console.log(count('hello','l'));
11.编写代码实现数组扁平化输出,例如:输入[[1,2,3,[4,5,6,[7,8]]],[9,10],[11,12,[13]],5]
输出为[1,2,3,4,5,6,7,8,9,10,11,12,13,5]
第一种方法:
function mout(arr){
var brr = arr.toString().split(',').map(function(item){
return Number(item);
})
return brr;
}
var arr = [[1,2,3,[4,5,6,[7,8]]],[9,10],[11,12,[13]],5];
console.log(mout(arr));
第二种方法:
function mout(arr){
if(!Array.isArray(arr))return arr;
var brr = [];
for(var i in arr){
var item = arr[i];
brr = brr.concat(mout(item));
}
return brr;
}
var arr = [[1,2,3,[4,5,6,[7,8]]],[9,10],[11,12,[13]],5];
console.log(mout(arr));