前端面试题(三)

  • js的基本数据类型

 Undefined、Null、Boolean、Number、String
ECMAScript6 新增:Symbol(创建后独一无二且不可变的数据类型 )
  •  call和apply的区别

var obj1 = {
  say:function(){
    console.log("say");
  }
}
var obj2 = {
  eat:function(name, age){
    console.log(this);
    console.log(name, age);
  }
}
//obj1.say();
//obj2.eat();
//obj2.eat.call(obj1);//为了让obj1执行eat方法,this的指向改变了
obj2.eat.call(obj1, "zh", 17);
obj2.eat.apply(obj1,["wang", 21]);
区别:call第二个参数开始接受一个参数列表
   apply第二个参数开始接受一个参数数组
  •  JavaScript如何实现继承?

原型链继承、借用构造函数继承、原型+构造函数组合继承、寄生式继承

//原型链继承
//构造方法继承
function Animal(){
  this.age = 20;
}
function Cat(){
  this.name = "jj";
  Animal.call(this);//这一步让Cat的对象借用了Animal对象的构造方法
}

//Cat.prototype = new Animal();//这一步让Cat的对象拥有Animal对象的属性、方法

var cat = new Cat();
//console.log(cat.name);
console.log(cat.age);
  • JavaScript创建对象的几种方式?

1、对象字面量、object构造函数
2、构造函数
3、纯构造函数
4、空构造函数+原型
5、混合构造函数+原型
6、动态原型
7、寄生构造函数
8、Object.create() -- ES5
//对象字面量
var obj = {};
obj.gender = "girl";
console.log(obj.gender);
console.log(obj["gender"]);//获取到obj的gender属性

//构造函数
var obj2 = new Object();//利用Object构造函数进行创建对象

//动态原型
  • JavaScript闭包
闭包:内层作用域可以访问外层作用域的变量
function doSth(){
    var len = 10;
    function step(){ //step函数为闭包函数
        console.log(len); //利用JavaScript的变量搜索机制,打印10;
     }  
}
闭包的意义:
1、让step这个函数只能在doSth里被调用,而且有封装了细节,如果把step放在全局作用域中,会污染全局作用域,并且占用了内存。
2、用来实现模块化

var common = (function(){
var name = "通用模块";
function initPage(){
console.log(name)
}
return{
initPage
}
})();
common.initPage();

3、例如一个页面有多个li标签,实现点击某一个弹出它是第几个
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>


var lis = document.querySelectorAll("li");//ES5支持的一个类似jQuery的复杂选择器的来选取DOM元素

for (var i = 0;i < lis.length;i++ ){
  var li = lis[i];
  //li.onclick=function(){
    //alert(i);//在触发这个函数时,i已经等于5了
    
  //}
  li.onclick = (function(index){
  //利用闭包函数实现了点击某个li标签的时候弹出他的真实索引
    return function(){
      alert(index);
    }
  })(i)
}
  • JavaScript的作用域

var num1 = 55;
var num2 = 66;

function f1(num, num1){//相当于在函数中先声明num,num1
  //var num = 55;
  //var num1 = 66;
  num = 100;
  num1 = 100;
  num2 = 100; //函数中没有声明num2,num2会访问函数外中的num2变量,此时num2的全局变量已经被改变为100
  console.log(num); //100
  console.log(num1); //100
  console.log(num2); //100
}
f1(num1,num2);//相当于把55和66传到f1函数当中
console.log(num1); //55
console.log(num2); //100
console.log(num); //报错
  • JavaScript值类型和引用类型的传递
function Person(name, age, salary){//构造函数首字母大写
  this.name = name;
  this.age = age;
  this.salary = salary;
}
function f1(person){
  //var person = p1;
  person.name = "lee";
  //person指向新的地址,但name值已经打印
  person = new Person('wang', 12, 10000);
}
var p1 = new Person('jia', 88, 90000);
console.log(p1.name);//jia
f1(p1);
console.log(p1.name);//lee
console.log(p1.age);//88
  • 封装一个函数,将字符串转化成驼峰表示法,如get-element-by-id 转化为 getElementById

原始方法:

var foo = "get-element-by-id";
var arr = foo.split("-");
//获取每个元素的第一个字符,并转换为大写
console.log(arr[1].charAt(0).toUpperCase() + arr[1].substr(1, arr[1].length-1));
//charAt() 方法可返回指定位置的字符。
//substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符。
for (var i = 1;i <arr.length;i++) {
  arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1, arr[1].length-1)
}
console.log(arr.join(""));
封装之后:
function toStr(foo){
    var arr = foo.split("-");
    for (var i = 1;i <arr.length;i++) {
          arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1, arr[1].length-1)
    }
    return arr.join("");
}
console.log(toStr("get-element-by-id"));
  • JavaScript冒泡排序

var arr = [5,4,8,2,1]
//轮数
for (var i = 0; i < arr.length;i++){
  //次数
  for(var j = 0;j < arr.length-1-i;j++){
    //前一个数和后一个数比较
    if(arr[j]>arr[j+1]){
      var temp = arr[j];
      arr[j] = arr[j+1];
      arr[j+1] = temp;
    }
  }
}
console.log(arr);
原文地址:https://www.cnblogs.com/strong-FE/p/10860540.html