Function

  1. 函数定义
  • 函数声明 function add () {}
  • 函数表达式 var add = function () {};
  • 对象实例化 var add = new Function() {};

//1.函数声明与函数表达式、对象实例化的区别

add1(1,1);
add2(1,2);
add3(1,3);
function add1(i, j){
  console.log(i+j);
}
var add2 = function(i, j){
  console.log(i+j);
}
var add3 = new Function("i", "j", "console.log(i+j);");

函数声明会实现声明提前,即使函数调用在函数定义之前依然可以调用
而函数表达式和函数对象实例化不行

//2.对象实例化与函数声明与函数表达式的区别
(function(){
  var i = 10;
  function add(j) {
    console.log(i+j);
    debugger;
  }
  add(1);
})();

(function(){
  var i = 10;
  var add = new Function("j", "console.log(i+j);debugger;");
  // add 函数这时属于全局,所以无法获得 i 
  add(1);
})();
  1. 构造函数
// 构造函数
function Car(type,color){
  this.type = type;
  this.color = color;
  this.status = "stop";
  this.light = "off";
}
Car.prototype.start = function(){
  this.status = "driving";
  this.light = "on";
  console.log(this.type + " is " + this.status);
}
Car.prototype.stop = function(){
  this.status = "stop";
  this.light = "off";
  console.log(this.type + " is " + this.status);
}
var audi = new Car("audi", "silver");
var benz = new Car("benz", "black");
var ferrari = new Car("ferrari", "yellow");
// 用构造函数实例化的对象可以直接获取和修改其内部的属性
// 如 audi.type = 'toyota';
// 显然这不是好的方式,它不能实现变量的私有化

// 还有其他内置的构造函数
// Boolean、String、Number、Object、Function、Array、Date、RegExp、Error
// 比如打印出对象
console.dir(new Boolean());
// 其结果如下
console.dir(new Boolean());
VM1866:2 Boolean__proto__: Booleanconstructor: Boolean()arguments: nullcaller: nulllength: 1name: "Boolean"prototype: Booleanconstructor: Boolean()toString: toString()valueOf: valueOf()__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()arguments: nullassign: assign()caller: nullcreate: create()defineProperties: defineProperties()defineProperty: defineProperty()deliverChangeRecords: deliverChangeRecords()freeze: freeze()getNotifier: getNotifier()getOwnPropertyDescriptor: getOwnPropertyDescriptor()getOwnPropertyNames: getOwnPropertyNames()getOwnPropertySymbols: getOwnPropertySymbols()getPrototypeOf: getPrototypeOf()is: is()isExtensible: isExtensible()isFrozen: isFrozen()isSealed: isSealed()keys: keys()length: 1name: "Object"observe: observe()preventExtensions: preventExtensions()prototype: Objectseal: seal()setPrototypeOf: setPrototypeOf()unobserve: unobserve()__proto__: ()<function scope>hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: get __proto__()set __proto__: set __proto__()[[PrimitiveValue]]: false__proto__: ()apply: apply()arguments: (...)get arguments: ThrowTypeError()set arguments: ThrowTypeError()bind: bind()call: call()caller: (...)get caller: ThrowTypeError()set caller: ThrowTypeError()constructor: Function()length: 0name: ""toString: toString()__proto__: Object<function scope><function scope>toString: toString()arguments: nullcaller: nulllength: 0name: "toString"__proto__: ()<function scope>valueOf: valueOf()arguments: nullcaller: nulllength: 0name: "valueOf"__proto__: ()<function scope>__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: get __proto__()set __proto__: set __proto__()[[PrimitiveValue]]: false[[PrimitiveValue]]: false
  1. 构造函数和普通函数的区别
  • 本质上没有什么区别

  • 构造函数的this会指向实例对象,并且this指定实例的属性 如:

    this.type = type;
    this.color = color;
    this.status = "stop";
    this.light = "off";

在原型对象上有一些公共方法 如:
Car.prototype.start = function(){
this.status = "driving";
this.light = "on";
console.log(this.type + " is " + this.status);
}
Car.prototype.stop = function(){
this.status = "stop";
this.light = "off";
console.log(this.type + " is " + this.status);
}

  • 构造函数命名首字母为大写
  1. 函数调用 (this)
    // 在每个函数中都有 this 和 arguments, this 根据调用方式不同,会绑定到不同的地方
  • 构造函数调用模式
    var Audi = new Car('Audi', 'silver');
    this 绑定到实例化对象 Audi 上 (new 绑定)
  • 方法调用模式
    (方法和函数的区别,方法是指绑定对象的函数,这只是一个名称上的规范)
    比如:
    Audi.start();
    // this 绑定到调用它的对象上
  • 函数调用模式
// 函数调用模式
function add(i, j){
  return i+j;
}
var myNumber = {
  value: 1,
  double: function(){
    var helper = function(){
        // this 指向的是 window
      this.value = add(this.value,this.value);
    }
    helper();
  }
}
myNumber.double() 
// 通过打印对象 console.dir(myNumber); value = 1;

// 解决方法是把this保存
function add(i, j){
  return i+j;
}
var myNumber = {
  value: 1,
  double: function(){
    var that = this;
    var helper = function(){
        that.value = add(that.value,that.value);
    }
    helper();
  }
}
myNumber.double() 
// 通过打印对象 console.dir(myNumber); value = 2;

// 注意:任何在函数内部调用的子函数 this 指向全局

- apply(call) 调用模式
var a = 2;
function foo() {
    return this.a;
}
var obj = {
    a: 3,
    foo: foo
}
obj.foo(); // 3
foo.call(obj); // 3
var bar = obj.foo;
bar(); // 2



// arguments转数组
function add(i, j) {
  var args = Array.prototype.slice.apply(arguments);
  args.forEach(function(item){
    console.log(item);
  })
}
add(1,2,3);


// arguments.callee使用
console.log(
  (function(i){
    if (i==0) {
      return 1;
    }
    return i*arguments.callee(i-1);
  })(5)
);


// 递归
function factorial(i){
  if (i==0) {
    return 1;
  }
  return i*factorial(i-1);
}


// 普通递归函数跟记忆函数调用次数对比
var factorial = (function(){
  var count = 0;
  var fac = function(i){
    count++;
    if (i==0) {
      console.log('调用次数:' + count); 
      return 1;
    }
    return i*factorial(i-1);
  }
  return fac;
})();
for(var i=0;i<=10;i++){
  console.log(factorial(i)); 
}

// 记忆函数
var factorial = (function(){
  var memo = [1];
  var count = 0;
  var fac = function(i){
    count++;
    var result = memo[i];
    if(typeof result === 'number'){
      console.log('调用次数:' + count); 
      return result;
    } 
    result = i*fac(i-1);
    memo[i] = result;
    return result;
  }
  return fac;
})();
for(var i=0;i<=10;i++){
  console.log(factorial(i)); 
}


// curry函数柯里化
function add(value){
   var helper = function(next){
      value = typeof(value)==="undefined"?next:value+next;
      return helper;
   }
   helper.valueOf = function(){
     return value;
   }
   return helper
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Function类型 函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和...
    胖胖冰阅读 943评论 0 8
  • 一、参考一个例子让你读懂什么是JS闭包[https://www.bilibili.com/video/BV16V4...
    合肥黑阅读 556评论 0 1
  • 一.通过关键字 function 定义 1.函数可以通过声明定义,也可以是一个表达式。1)声明:function ...
    小甜妮子__阅读 447评论 0 0
  • Function类型 每个函数都是Function类型的实例,因此函数名实际上也是一个指向函数对象的指针 一、函数...
    McRay阅读 132评论 0 1