JS高级语法十个重点和难点

JS高级语法十个重点和难点

一、立即执行函数

函数在进行定义的时候就立即执行

// 定义函数
function getName(){
    console.log('你的名字')
}
// 调用函数
getName()
(function(){
    console.log('立即执行函数')
})()

二、闭包

闭包是函数内部可以使用函数外部的变量

function f1(){
   var n = 1;
   function f2(){
       n+1;
       console.log(n)
   }
   return f2
}
var result = f1();
result()//2
result()//3
result()//4

三、使用闭包定义私有变量

使用闭包定义私有变量,只能在函数内部进行使用

function f1(){
    var name = '彦祖';
    this.GetName = function(){
        return name
    }
    this.SetName = function(value){
        name = value
    }

}
var s1 = new f1();
console.log(s1.name)//undefined
console.log(s1.GetName())//彦祖

四、原型和原型链

JavaScript所有的构造函数都有一个原型对象prototype,用于设置所有实例对象需要共享的属性和方法

function Rectangle(x,y){
    this._length = x;
    this._breadth = y
}
Rectangle.prototype.getDimensions = function(){
    return {
        length:this._length,
        breadth:this.breadth
    }
}
var x = new Rectangle(3,4);
var y = new Rectangle(4,3);
console.log(x.getDimensions());
console.log(y.getDimensions());

五、模块化

JavaScript并非模块化编程语言,至少在ES6之前不是这样的,但是对于一个复杂的应用来讲,模块化是最基本的一个要求。

var module = (function(){
    var N = 5;
    function print(x){
        console.log("The result is :"+x);
    }
    function add(a){
        var x = a+N;
        print(x)
    }
    return {
        description:'this is description';
        add:add
    }
})()

六、变量提升

JavaScript会将所有变量和函数声明移动到他作用域的最前面,这就是变量提升

console.log(y);
var y = 2;

等价于

var y;
console.log(y);
y = 2

七、柯里化

柯里化,可以使函数变得更加灵活,我们可以一次性传入多个参数调用他,也可以只传入一个参数调用它,让他返回一个函数去处理剩下的参数。

var add = function(x){
    return function(y){
        return x+y;
    }
}
console.log(add(1)(1));
var add1 = add(1);
console.log(add1(1));
var add10 = add(10);
console.log(add10(1));

八、apply,call,bind的用法

这三个方法都是改变函数内部this的指向

  • 三个方法的第一个参数都是this的指向
  • 第二个参数是传递的参数
  • call和apply都会执行函数,bind是返回一个函数
①:函数.call(对象,arg1,arg2....)
②:函数.apply(对象,[arg1,arg2,...])
③:var ss=函数.bind(对象,arg1,arg2,....)

九、Memoization

Memoization 的原理就是把函数的每次执行结果都放入一个对象中,在接下来的执行中,在对象中查找是否已经有相应执行过的值,如果有,直接返回该值,没有才真正执行函数体的求值部分。在对象里找值是要比执行函数的速度要快的。

let memoize = function(func) {
  let cache = {};
  return function(key) {
    if (!cache[key])
      cache[key] = func.apply(this, arguments);
    return cache[key];
  }
}

underscore 的源码中有 Memoization 方法的封装,它支持传入一个 hasher 用来计算缓存对象 key 的计算方式。

_.memoize = function(func, hasher) {
  var memoize = function(key) {
    // 把存储对象的引用拿出来,便于后面代码使用
    var cache = memoize.cache;
 
    // hasher 是计算 key 值的方法函数。
    // 如果传入了 hasher,则用 hasher 函数来计算 key
    // 否则用 参数 key(即 memoize 方法传入的第一个参数)当 key
    var address = '' + (hasher ? hasher.apply(this, arguments) : key);
 
    // 如果 key 还没有对应的 hash 值(意味着没有缓存值,没有计算过该输入)
    // 就执行回调函数,并缓存结果值
    if (!_.has(cache, address))
      cache[address] = func.apply(this, arguments);
 
    // 从缓存对象中取结果值
    return cache[address];
  };
 
  // cache 对象被当做 key-value 键值对缓存中间运算结果
  memoize.cache = {};
 
  // 返回 momoize 函数, 由于返回函数内部引用了 memoize.cache, 构成了闭包,变量保存在了内存中。
  return memoize;
};

质数为在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数。

function isPrime(value) {
  console.log("isPrime 被执行了!");
  var prime = value != 1; // 1 不是素数,其他数字默认是素数。
  for (var i = 2; i < value; i++) {
    if (value % i == 0) {
      prime = false;
      break;
    }
  }
  return prime
}
 
let momoizedIsPrime = memoize(isPrime);
 
momoizedIsPrime(5) // isPrime 被执行了!
momoizedIsPrime(5) // 第二次执行,没有打印日志!

斐波那契数列的特点是后一个数等于前面两个数的和

指的是这样一个数列:1、1、2、3、5、8、13、21、……在数学上,斐波那契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2

fibonacci = memoize(fibonacci);
for(var i = 0; i<= 10; i++) {
    console.log(`i: ${i}, ` + fibonacci(i));
}
console.log(count); // 12

十、函数重载

function comeon() {
    document.writeln("无参一身轻");
    document.write("<br>");
}
function comeon(i) {
    document.writeln("一参是为"+i);
    document.write("<br>");
}
function comeon(i,j){
    document.writeln("二参数更有"+i+"和"+j);
    document.write("<br>");
}

comeon();
comeon(1);
comeon(1,2);
  • 问题:后面的函数会覆盖之前的函数
function add(){
    if(arguments.length==0){
        document.writeln("没有参数,你让我加什么?");
        document.write("<br>");
    }
    else if(arguments.length==1){
        document.writeln(arguments[0]);
        document.write("<br>");
    }
    else
    {
        var n = 0;
        len = arguments.length;
        for (var i = 0; i < len; i++) {
            n+=arguments[i];
        }
        document.writeln(n);
        document.write("<br>");
    }
}
add();
add(1);
add(1,2);
add(1,2,3);
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值