微专业知识点总结

Posted by liyaozr on March 24, 2017

准备把微专业的课堂讨论总结一下,毕竟都是知识点啊!部分答案来源于网络··

还未总结完,更新中

1、JPG、PNG8、PNG24这些格式分别适合保存什么特点的图片?

JPG:

  1. 适用范围: ①图片色彩丰富 ②对透明度没有要求

  2. 保存格式设置: 品质:根据项目要求调整;

PNG8:

  1. 适合范围: ①色彩不太丰富 ②对透明度没有要求的图片

  2. 保存格式设置: 仿色:无仿色; 杂边:无;

PNG24:

  1. 适合范围:有透明度要求的图片

  2. 保存格式:一般默认格式,无需修改

2、图片分类合并有哪些方式? 分类合并的方法(即先分类再合并,保留空隙,一般20像素左右):

  1. 把同属于一个模块的图片进行合并;
  2. 把大小相近的图片进行合并;
  3. 把色彩相近的图片进行合并;
  4. 综合以上方式合并。

合并推荐方法:

  1. 只本页面用到的图片合并;
  2. 有状态的图标合并。

3、如何实现浏览器兼容版的inline-block显示 直接让块元素设置为内联对象呈递(设置属性display:inline),然后触发块元素的layout(如:zoom:1 或float属性等)

div { display:inline-block; _zoom:1;_display:inline;}

4、如何获取一个大于等于0且小于等于9的随机整数?

var num = Math.floor(Math.random()*10);

5、想要去除一个字符串的第一个字符,有哪些方法可以实现(方法有待更新)

var str="wangyi";
str.replace(str.charAt(0),"");
str.slice(1);
str.substring(1);
str.substr(1);

6、对一个数组(每项都是数值)求和,有哪些方法?(方法有待更新) for循环

  var arr = [0,1,2,3,4,5,6,7,8,9];
       var sum = 0;
      for (var i = 0; i < arr.length; i++) {
          sum+=parseInt(arr[i]);
      }
      document.write(sum); 

while
      var arr = [0,1,2,3,4,5,6,7,8,9];
      var sum = 0;
      var i = arr.length;
      while (i--) {
            sum += parseInt(arr[i]);
      }
      document.write(sum);

forEach()
      var arr = [0,1,2,3,4,5,6,7,8,9];
      var sum=0;
      arr.forEach(function(item,index,array){
                sum+=item;
        });
        document.write(sum);

map()
      var arr = [0,1,2,3,4,5,6,7,8,9];
      var sum=0;
      arr.map(function(item,index,array){
                sum+=item;
        });
        document.write(sum);

reduce()
      var arr = [0,1,2,3,4,5,6,7,8,9];
      var sum=arr.reduce(function(previous, current, index, array) {
          return previous + current;
        });
        document.write(sum);

正则表达式中,量词的贪婪模式与惰性模式有什么区别? 贪婪匹配表示在符合规则的前提下尽可能匹配多的字符。 懒惰则表示匹配尽可能少的字符。 参考网站 http://deerchao.net/tutorials/regex/regex.htm#greedyandlazy

JSON.stringify兼容 方法一:直接引用json2.js文件。 从网上下载json2.js文件。 下载地址:https://github.com/douglascrockford/JSON-js#/learn/_blank 在页面中引用该脚本:

<script type="text/javascript" src="js/json2.js"></script>

方法二:使用如下代码:

if(!window.JSON){
    window.JSON = {
        stringify: function(obj){
            var result = "";
            for(var key in obj){
                if(typeof obj[key] == "string"){
                    // 如果属性值是String类型,属性值需要加上双引号
                    result += "\"" + key + "\":\"" + obj[key] + "\",";
                }else if(obj[key] instanceof RegExp){
                    // 如果属性是正则表达式,属性值只保留一对空大括号{}
                    result += "\"" + key + "\":{},";
                }else if(typeof obj[key] == "undefined" || obj[key] instanceof Function){
                    // 如果属性值是undefined, 该属性被忽略。忽略方法。
                }else if(obj[key] instanceof Array){
                    // 如果属性值是数组
                    result += "\"" + key + "\":[";
                    var arr = obj[key];
                    for(var item in arr){
                        if(typeof arr[item] == "string"){
                            // 如果数组项是String类型,需要加上双引号
                            result += "\"" + arr[item] + "\",";
                        }else if(arr[item] instanceof RegExp){
                            // 如果属数组项是正则表达式,只保留一对空大括号{}
                            result += "{},";
                        }else if(typeof arr[item] == "undefined" || arr[item] instanceof Function){
                            // 如果数组项是undefined, 则显示null。如果是函数,则显示null?。
                            result += null +",";
                        }else if(arr[item] instanceof Object){
                            //如果数组项是对象(非正则,非函数,非null),调用本函数处理
                            result += this.stringify(arr[item]) +",";
                        }else{
                            result += arr[item] + ",";
                        }
                    }
                    result = result.slice(0,-1)+"],"
                }else if(obj[key] instanceof Object){
                    // 如果属性值是对象(非null,非函数,非正则),调用本函数处理
                    result += "\"" + key + "\":" + this.stringify(obj[key]) + ",";
                }else{
                    result += "\"" + key + "\":" + obj[key] + ",";
                }
            }
            // 去除最后一个逗号,两边加{}
            return "{" + result.slice(0,-1) + "}";
        }
    };
}

如何复制一个对象?

我们知道,对象作为引用类型,使用运算符=时,只是复制了对象的地址。那么如果我们需要克隆出一个独立但属性、方法完全一样的对象,该如何实现?

//返回传递给他的任意对象的类    
        function isClass(o){
            if(o===null) return "Null";
            if(o===undefined) return "Undefined";
            return Object.prototype.toString.call(o).slice(8,-1);
        }
//深度克隆
        function deepClone(obj){
            var result,oClass=isClass(obj);
                //确定result的类型
            if(oClass==="Object"){
                result={};
            }else if(oClass==="Array"){
                result=[];
            }else{
                return obj;
            }
            for(key in obj){
                var copy=obj[key];
                if(isClass(copy)=="Object"){
                    result[key]=arguments.callee(copy);//递归调用
                }else if(isClass(copy)=="Array"){
                    result[key]=arguments.callee(copy);
                }else{
                    result[key]=obj[key];
                }
            }
            return result;
        }
        //返回传递给他的任意对象的类
        function isClass(o){
            if(o===null) return "Null";
            if(o===undefined) return "Undefined";
            return Object.prototype.toString.call(o).slice(8,-1);
        }
        var oPerson={
            oName:"rookiebob",
            oAge:"18",
            oAddress:{
                province:"beijing"
            },    
            ofavorite:[
                "swimming",
                {reading:"history book"}
            ],
            skill:function(){
                console.log("bob is coding");
            }
        };
        //深度克隆一个对象
        var oNew=deepClone(oPerson);
          
        oNew.ofavorite[1].reading="picture";
        console.log(oNew.ofavorite[1].reading);//picture
        console.log(oPerson.ofavorite[1].reading);//history book
          
        oNew.oAddress.province="shanghai";
        console.log(oPerson.oAddress.province);//beijing
        console.log(oNew.oAddress.province);//shanghai

JS和强类型语言(比如C++)在类型方面的主要区别?

强类型定义语言:强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语言是类型安全的语言。

弱类型定义语言:数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。

二者的区别,在于计算时是否可以不同类型之间对使用者透明地隐式转换。从使用者的角度来看,如果一个语言可以隐式转换它的所有类型,那么它的变量、表达式等在参与运算时,即使类型不正确,也能通过隐式转换来得到正确地类型,这对使用者而言,就好像所有类型都能进行所有运算一样,所以这样的语言被称作弱类型。 与此相对,强类型语言的类型之间不一定有隐式转换(比如C++是一门强类型语言,但C++中double和int可以互相转换,但double和任何类型的指针之间

JS中有哪些场景会出现隐式类型转换? (1)数字运算符操作 : 数字与字符串进行加法操作时,数字会被隐式转为为字符串;其他数字与字符串的运算符操作时,字符串会隐式转换为对应的数字; 一元运算符也会把运算子转换为数值:例如:+’abc’ // NaN -‘abc’ // NaN +true // 1 -false // 0 (2).运算符 会把字面量隐式转换为对应的对象类型来调用对象原型上的方法 (3)if语句 (条件部分默认转换为布尔类型) undefined ,null,-0,0,+0,NaN,’‘(空字符串)这几种会自动转换为false,其他就默认转换为true (4)== 不完全等号在进行运算时,会发生隐式类型的转换

JS中有哪些识别类型的方法(包括用于识别某种具体类型的方法)?

  • typeof: 1、可以识别标志类型(null除外) 2、不可识别具体的对象类型

  • instanceof 1、能够判别内置对象类型 2、不能判别原始类型 3、能够判别自定义类型
  • Object.prototype.toString.call() 1、可以识别标准类型,及内置对象类型 2、不能识别自定义类型

  • constuructor 1、可判别标准类型(undefined/null除外) 2、可判别内置对象类型 3、可识别自定义类型

函数声明和函数表达式定义同一个函数时,执行的是哪个?

// 以下代码执行时,三次打印分别输出什么?为什么?
 
function add1(i){
  console.log("函数声明:"+(i+1));
}
add1(1);
 
var add1 = function(i){
  console.log("函数表达式:"+(i+10));
}
add1(1);
 
function add1(i) {
    console.log("函数声明:"+(i+100));
}
add1(1);

对象方法中定义的子函数,子函数执行时this指向哪里? 三个问题: 以下代码中打印的this是个什么对象? 这段代码能否实现使myNumber.value加1的功能? 在不放弃helper函数的前提下,有哪些修改方法可以实现正确的功能?

var myNumber = {
  value: 1,
  add: function(i){
    var helper = function(i){
        console.log(this);
          this.value += i;
    }
    helper(i);
  }
}
myNumber.add(1);

1.this指向Window全局变量 2.不能,因为window没有value属性 3.实现方法

//方法一:可以把helper调整为方法函数,这样helper就可以正确引用myNumber为this了            
       var myNumber = {
               value:1,
               helper:function(i) {
                       console.log(this);
                       this.value +=i;
               },
               add: function(i) {
                   this.helper(i);
               }            
           }
       myNumber.add(1);
//方法二:使用闭包      
        var myNumber = {
           value: 1,
           add: function(i){
               var thisnew = this;
               // 构建闭包
               var helper = function(i){
                   console.log(thisnew);
                   thisnew.value += i;
               }
              helper(i);
            }
       }
       
//方法三:使用apply(call)调用模式,将当前helper方法借用给myNumber对象使用,这样this指向的就是myNumber对象    
       var myNumber = {
           value: 1,
           add: function(i){
               var helper = function(i){
                   console.log(this);
                   this.value += i;
               }
               // myNumber对象借用helper方法,helper中的this将指向myNumber对象
               helper.apply(myNumber,[i]); //apply方法
               helper.call(myNumber,i);  //call方法
           }
       }
           
//方法4,最笨的一种,针对这个题目只要不用this.value改成myNumber.value就可以了
var myNumber = {
  value: 1,
  add: function(i){
    var helper = function(i){
           
        console.log(this);
          myNumber.value += i;
    }
      
    helper(i);
  }
}
myNumber.add(1);

在变量作用域方面,函数声明和函数表达式有什么区别? 主要区别在于是否提前初始化 函数声明:函数被执行前就已被初始化,和调用顺序没有关系。 函数表达式:只有执行到该定义是,函数才被初始化,和调用顺序有关, 在with语句或者try catch 语句内,作用域可能被改变。 闭包的应用场景有哪些?试举例说明 1)保存函数的执行状态 实例1:

  • 将字符串中的一些特定字符按顺序用数组中的元素替换,例如: var arr = [‘c’,’f’,’h’,’o’]; var str = ‘ab4de8g4ijklmn7’; 替换后 str == ‘abcdefghijklmno’;
    var arr = ['c','f','h','o'];
    var str = 'ab4de8g4ijklmn1';
    console.log(str);
    // 使用闭包,可以让函数记住自身被调用的状态
    var func = (function(){
      // count变量会保存在闭包作用域内,表示func被调用次数(即正在替换第几个字符)
      var count = 0;
      return function(){
     return arr[count++];
      };
    })();
    str = str.replace(/\d/g, func);
    console.log(str);
    

2)封装 1.暴露type类型和start, stop, getStatus方法 2.隐藏status,light对象状态

var Car = function(type){
  var status = "stop",
      light = "off";
  return {
    type: type,
    start: function(){
      status = "driving";
      light = "on";
    },
    stop: function(){
      status = "stop";
      light = "off";
    },
    getStatus: function(){
      console.log(type + " is " + status + " with light " + light);
    }
    };
};
var audi = new Car("audi");
audi.start();
audi.getStatus();
audi.stop();
audi.getStatus();

3)性能优化 减少函数定义时间和内存消耗 —-不使用闭包

function sum(i, j) {
  var add = function(i, j){
    return i+j;
  }
  return add(i, j)
}
var startTime = new Date();
for(var i = 0; i< 1000000; i++) {
  sum(1,1);        //每次执行sum都要在sum内部定义add这个函数,浪费时间
}
var endTime = new Date();
console.log(endTime - startTime);     //187ms

—-使用闭包

var sum = (function() {
  var add = function(i, j){
    return i+j;
  }
  return function(i,j) {
    add(i, j);
  }
})()
var startTime = new Date();
for(var i = 0; i< 1000000; i++) {
  sum(1,1);        
}
var endTime = new Date();
console.log(endTime - startTime);   //19ms

原型继承和类继承有什么区别? 参考网站

https://75team.com/post/inherits.html

http://web.jobbole.com/83319/

http://www.zcfy.cc/article/master-the-javascript-interview-what-s-the-difference-between-class-amp-prototypal-inheritance-2185.html

实现一个Circle类

编程实现: a.创建一个圆(Circle)的类,并定义该类的一个属性(半径)和两个方法(周长和面积),其中圆的半径可以通过构造函数初始化 b.创建圆的一个对象,并调用该对象的方法计算圆的周长和面积

请使用Js代码写出一个类继承的模型,需包含以下实现:

1.定义父类和子类,并创建父类和子类的属性和方法 2.子类继承父类的属性和方法 3.在创建子类对象时,调用父类构造函数