JavaScript引用类型——Function


撸了今年阿里、头条和美团的面试,我有一个重要发现…>>>
Function类型
函数实际上是对象,每个函数实际上都是 Function 类型的实例。而且与其他引用类型一样具有属性和方法。函数名实际上是一个指向内存堆中某个函数对象的指针。不会与函数绑定。函数可以如下面的语法定义:

function sum (num1, num2){
    return num1 + num2;
}
    也可以像下面一样定义:

var sum = function(num1, num2){
    return num1 + num2;
}
还可以使用Function构造函数。Function构造函数可以接收任意数量的参数,最后一个参数始终被看做函数体,前面的参数被看做是新函数的参数。

var sum = new Function("num1","num2","return num1 + num2");
这种方式会导致解析两次代码(第一次是解析常规ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能。

1、函数没有重载
在ECMAScript中没有函数重载。因为函数名是作为指针的概念存在的,重复声明同一个函数名相当于覆盖指针引用,所有同一个函数名同时只能保存一个函数引用。

function fn(num1){
    return num1;
}

function fn(num1, num2){
    return num1 + num2;
}

console.log(fn(1));//NaN
    上面的代码以下面相同:

var fn = function(num1){
    return num1;
}

var fn = function(num1,num2){
    return num1 + num2;
}

console.log(fn(1));//NaN

2、函数声明与函数表达式的区别
函数声明与函数表达式的语法功能相同,但是其解析的过程却是不同的。解析器会先读取函数声明,并使其在任何执行代码前,就是说解析器会先扫描脚本,然后将声明的函数置于脚本顶部,以便于接下来执行的可以调用函数。这样就可以解释为是声明的函数可以在声明之前调用。

console.log(sum(1,2));//3
function sum(num1,num2){
    return num1 + num2;
}
    而对于函数表达式,解析器则会当作普通的赋值操作,而不会对其进行特殊的解析。下面代码会抛异常。

console.log(sum(1,2));//unexpected identifier
var sum = function(num1,num2){
    return num1 + num2;
}

3、函数内部属性
函数内部有两个特殊的对象:arguments和this。arguments是一个数组对象,包含传入函数的所有参数arguments对象有一个名叫callee的属性,指向拥有这个arguments对象的函数。对比下面的例子:

function factorial(num){
    if(num <= 1){
        return 1;
    } else {
        return num * factorial(num - 1);
    }
}
function factorial(num){
    if(num <= 1){
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}
第一个函数中引用了函数名,这回导致函数改名时不可用,而,第二个函数则没有这个问题。

函数内部还有一个特对象this,引用函数数据以执行的环境对象。

window.color = "red";
var o = {color:"blue"};

function sayColor(){
    console.log(this.color);
}

sayColor();//"red"

o.sayColor = sayColor;
o.sayColor();//"blue"
还有另外一个属性:caller。保存调用当前函数的引用,如果在全局作用域中调用,值为null。

function outer(){
    inner();
}

function inner(){
    console.log(arguments.callee.caller);
}

outer();

4、函数属性和方法
ECMAScript中的函数是对象,也有属性和方法。每个函数都有两个属性:length和prototype。其中,length属性表示函数要接收的命名函数的个数。

function sayName(name){
    console.log(name);
}

function sum(num1, num2){
    return num1 + num2;
}

function sayHi(){
    console.log("hi");
}

console.log(sayName.length);//1
console.log(sum.length);//2
console.log(sayHi.length);//0
每个函数包含两个非继承而来的方法:apply()和call()。apply()方法接收两个参数:一个是在其中运行函数的作用越,另一个是参数数组。第二参数可以是Array实例,也可以是arguments对象。

function sum(num1, num2){
    return num1 + num2;
}

function callSum1(num1, num2){
    return sum.apply(this,arguments);//传入arguments对象
}

function callSum2(num1, num2){
    return sum.apply(this, [num1,num2]);//传入数组
}

console.log(callSum1(10,10));//20
console.log(callSum2(10,10));//20
    对于call(),第一个参数this没有变化,但是其他参数需要直接传递函数。

function sum(num1, num2){
    return num1 + num2;
}

function callSum(num1, num2){
    return sum.call(this, num1,num2);//传入数组
}

console.log(callSum(10,10));//20
    apply()和call()能够扩充函数运行的作用域。

window.color = "red";
var o = {color : "blue"};

function sayColor(){
    console.log(this.color);
}

sayColor();//red

sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue
    ECMAScript 5定义了一个方法:bind()。

window.color = "red";
var o = {color : "blue"};

function sayColor(){
    console.log(this.color);
}

var objectSayColor = sayColor.bind(o);
objectSayColor();//blue
支持bind()方法的浏览器有IE9+、FF4+、Safari5.1+、Opera 12+和Chrome。

这份 xmind 尤其适合: https://my.oschina.net/u/2663968/blog/3105068

1.近期想跳槽,要面试的Java程序员,查漏补缺,以便尽快弥补短板;

2.想了解“一线互联网公司”最新技术要求,对比找出自身的长处和弱点所在,评估自己在现有市场上的竞争力如何;

3.做了几年Java开发,但还没形成系统的Java知识体系,缺乏清晰的提升方向和学习路径的程序员。

----------------------------头条一面试题
上来先网络问题

说说TCP UDP区别
http状态码301 302区别? 状态码分几大类? https如何使用密钥保证可靠性

面试管可能觉得网络不行,那咱就换个话题吧

说说let const区别 (可惜 唉 const居然说不知道)
call applly bind区别? 请模拟一个bind函数. (答对一半 我也是懵逼 不是有吗 要自己造)
使用正则表达式讲"< %=% >“转换为”{ %}" (又挂了 面试官还是很热心 继续提问 给个简单的)
判断JS为空对象 (这个还行 当时用 JSON.stringify(obj) == ‘{}’) 找出数组中第二大的数.
如arr=[9,2,5,0,6…] (这个还行 当时先排序 在找) creator性能优化讲讲

在这里插入图片描述最好结果呢 不言而喻

1 如何模拟bind函数? 泪崩 可惜太菜 当时没回答商量

var obj = {
    name:'zhangsan',
    showLog:function(){ ...... }
}
var obj2 = {
    name:'LiMing'
};
obj.showLog().bind(obj2);
过了几天才相处办法  ....
function bind2(obj){
    let func = bind2.caller.toString(); // func.caller返回调用当前函数的那个函数
    obj[func] = arguments.callee;      // caller 保存调用当前函数的引用<意思函数指针/地址>
    return obj[func];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
探索全栈前端技术的魅力:HTML+CSS+JS+JQ+Bootstrap网站源码深度解析 在这个数字化时代,构建一个既美观又功能强大的网站成为了许多开发者和企业追逐的目标。本份资源精心汇集了一套完整网站源码,融合了HTML的骨架搭建、CSS的视觉美化、JavaScript的交互逻辑、jQuery的高效操作以及Bootstrap的响应式设计,全方位揭秘了现代网页开发的精髓。 HTML,作为网页的基础,它构建了信息的框架;CSS则赋予网页生动的外观,让设计创意跃然屏上;JavaScript的加入,使网站拥有了灵动的交互体验;jQuery,作为JavaScript的强力辅助,简化了DOM操作与事件处理,让编码更为高效;而Bootstrap的融入,则确保了网站在不同设备上的完美呈现,响应式设计让访问无界限。 通过这份源码,你将: 学习如何高效组织HTML结构,提升页面加载速度与SEO友好度; 掌握CSS高级技巧,如Flexbox与Grid布局,打造适应各种屏幕的视觉盛宴; 理解JavaScript核心概念,动手实现动画、表单验证等动态效果; 利用jQuery插件快速增强用户体验,实现滑动效果、Ajax请求等; 深入Bootstrap框架,掌握移动优先的开发策略,响应式设计信手拈来。 无论是前端开发新手渴望系统学习,还是资深开发者寻求灵感与实用技巧,这份资源都是不可多得的宝藏。立即深入了解,开启你的全栈前端探索之旅,让每一个网页都成为技术与艺术的完美融合!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值