下面属于javascript内部对象的有_JavaScript基础内容中闭包以及常用函数

接上文,JavaScript基础内容中的函数。

我们这次把函数剩下的全部分享完。各位可要用心看喽。

11、bind

bind 是创建了一个新函数而不是修改一个函数。新函数的行为和原来函数的行为一样,但他的接收者是我们给定的对象,而原有函数的接收者保持不变。

function f(){
    return this.a;
}

var g = f.bind({a:"azerty"});

console.log(g()); // azerty

var o = {a:37, f:f, g:g};

console.log(o.f(), o.g()); // 37, azerty

12、 匿名函数立即调用

(function(a,b){
    alert(a+b);
})(1,2);

13、 函数的闭包

目前先了解,后期见多了,就知道作用了函数的内部,还可以定义另一个函数,这就是闭包(closure),即定义在函数体内部的函数。闭包只在声明它的函数内部有效。

function f() {
    var c = function() {};
}

上面的代码中,c 是定义在函数 f 内部的函数,因此 c 就是 f 的闭包。

一旦外层函数返回闭包,我们就可以通过闭包,从外部读取函数的内部变量

function f() {
    var v = 1;

    var c = function (){
        return v;
    };

    return c;
}

var o = f();
o() // 1

闭包不仅可以读取函数内部变量,还可以使得内部变量记住上一次调用时的运算结果。

function createIncrementor(start) {
    return function () {
        return start++;
    };
}

var inc = createIncrementor(5);
inc() // 5
inc() // 6
inc() // 7

14、 常用函数

a)、字符串

◦ charAt(idx):返回指定位置处的字符

◦ indexOf(Chr):返回指定子字符串的位置,从左到右。找不到返回-1

◦ substr(m,n):返回给定字符串中从 m 位置开始,取 n 个字符,如果参数 n 省略,则意味着取到字符串末尾。

◦ substring(m,n):返回给定字符串中从 m 位置开始,到 n 位置结束,如果参数 n省略,则意味着取到字符串末尾。

◦ toLowerCase():将字符串中的字符全部转化成小写。

◦ toUpperCase():将字符串中的字符全部转化成大写。

◦ length: 属性,不是方法,返回字符串的长度。

b)、数学

◦ Math.random()

◦ Math.ceil() :天花板 大于最大整数

◦ Math.floor() :地板 小于最小整数

c)、日期

◦ getyear, getmonth, …

◦ setyear, setmonth, …

◦ toLoacaleString()

<div id="dv001" onclick="Clock(this);">clickdiv>
/*
- param clockDiv
- 传入的 div 对象
*/
function Clock(clockDiv) {
    this.clockDiv = clockDiv;

    this.getCurrentDate = function() {
        // 获取当前日期
        var currDate = new Date();

        // 分别获取 年、月、日、时、分、秒
        var currDateTime = currDate.getYear();

        currDateTime += "-";
        currDateTime += (currDate.getMonth() + 1);
        currDateTime += "-";
        currDateTime += currDate.getDate();
        currDateTime += " ";
        currDateTime += currDate.getHours();
        currDateTime += ":";
        currDateTime += currDate.getMinutes();
        currDateTime += ":";
        currDateTime += currDate.getSeconds();
        return currDateTime;
    }();
    // 将当前时间赋值到 div 对象中
    this.clockDiv.innerHTML = this.getCurrentDate;
}
e)、编码与解码 :

中文在计算机世界里面不占优势,外国人发明的,再说中文文字也太多:

编码:encodeURI() -->编码参数【key=value】、 encodeURIComponent()-->编码所有 【整个uri地址编码】

解码:decodeURI() 、decodeURIComponent()

alert(encodeURI("http://www.baidu.com/index.jsp?姓名=王大锤"));
alert(encodeURIComponent("http://www.baidu.com/index.jsp?uname=王大锤"));
alert(decodeURI("http://www.baidu.com/index.jsp?uname=%E7%8E%8B%E5%A4%A7%E9%94%A4"));
alert(decodeURIComponent("http://www.baidu.com/index.jsp?uname=王大锤"));

15、 this

函数的难点之: this:

this 指定了上下文对象,当然如果没有指定就会指定到全局变量,window ;JavaScript 是一种脚本语言,支持函数式编程、闭包、基于原型的继承等高级功能。JavaScript 一开始看起来感觉会很容易入门,但是随着使用的深入,你会发现 JavaScript其实很难掌握,有些基本概念让人匪夷所思。其中 JavaScript 中的 this 关键字,就是一个比较容易混乱的概念,在不同的场景下,this 会化身不同的对象。有一种观点认为,只有正确掌握了JavaScript 中的 this 关键字,才算是迈入了 JavaScript 这门语言的门槛。在主流的面向对象的语言中(例如 Java,C#等),this 含义是明确且具体的,即指向当前对象。一般在编译期绑定。而 JavaScript 中 this 在运行期进行绑定的,这是JavaScript 中 this 关键字具备多重含义的本质原因。JavaScript 由于其在运行期进行绑定的特性,JavaScript 中的 this 可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用 apply 或 call调用。常言道,字不如表,表不如图。为了让人更好的理解 JavaScript this 到底指向什么?下面用一张图(JavaScript this 决策树)来进行解释:

var point = {
    x : 0,
    y : 0,
    moveTo : function(x, y) {
        this.x = this.x + x;
        this.y = this.y + y;
    }
};

point.moveTo(1,1); //this 绑定到当前对象,即 point 对象

point.moveTo()函数在 "JavaScript this 决策树"中进行判定的过程是这样的:

1)point.moveTo 函数调用是用 new 进行调用的么?这个明显不是,进入“否”分支,即函数是否用 dot(.)进行调用?;

2)point.moveTo 函数是用 dot(.)进行调用的,即进入“是”分支,即这里的 this指向 point.moveTo 中.之前的对象 point;

图解 point.moveTo 函数的 this 指向什么的解析图如下图所示:

a749beac9bcbb59fb1611f0bd1b4ed86.png

再举例,看下面的代码:

function func(x) {
    this.x = x;
}

func(5); //this 是全局对象 window,x 为全局变量
x;//x => 5

func()函数在 "JavaScript this 决策树(非严格模式)"中进行判定的过程是这样的:

b51315ad88a1adba6a4b55925141f22f.png

严格模式是一种将更好的错误检查引入代码中的方法。在使用严格模式时,无法使用隐式声明的变量、将值赋给只读属性或将属性添加到不可扩展的对象等

1、 严格模式的目的

1) 消除 Javascript 语法的一些不合理、不严谨之处,减少一些怪异行为

2)消除代码运行的一些不安全之处,保证代码运行的安全

3) 提高编译器效率,增加运行速度

4) 为未来新版本的 Javascript 做好铺垫

2、声明严格模式

可以通过在文件、程序或函数的开头添加 "use strict"; 来声明严格模式。此类声明称作“指令序言”。严格模式声明的范围取决于其上下文。如果在全局上下文(函数的范围之外)中声明严格模式,则程序中的所有代码都处于严格模式。如果在函数中声明严格模式,则函数中的所有代码都处于严格模式。

"use strict"; // see strict mode

function testFunction(){
    var testvar = 4;
    return testvar;
}

// This causes a syntax error.
testvar = 5;

function f1(){
    return this;
}

console.log(f1() === window); // global object  false

function f2(){
    "use strict"; // see strict mode
    return this;
}

console.log(f2() === undefined);//true

针对作为函数直接调用的方式,下面看一个复杂的例子:

var point = {
    x : 0,
    y : 0,

    moveTo : function(x, y) {
        // 内部函数
        var moveX = function(x) {
            this.x = x;//this 指向什么?window
        };

        // 内部函数
        var moveY = function(y) {
            this.y = y;//this 指向什么?window
        };

        moveX(x);
        moveY(y);
    }
};

point.moveTo(1,1);
point.x; //=>0
point.y; //=>0

x; //=>1
y; //=>1

point.moveTo(1,1)函数实际内部调用的是 moveX()和 moveY()函数, moveX()函数内部的 this 在"JavaScript this 决策树"中进行判定的过程是这样的:

1)moveX(1)函数调用是用 new 进行调用的么?这个明显不是,进入“否”分支,即函数是否用 dot(.)进行调用?;

2)moveX(1)函数不是用 dot(.)进行调用的,即进入“否”分支,即这里的 this 指向全局变量 window,那么 this.x 实际上就是 window.x;

下面看一下作为构造函数调用的例子:

function Point(x,y){
    this.x = x; // this ?
    this.y = y; // this ?
}

var np=new Point(1,1);
np.x;//1
var p=Point(2,2); //没有 return 就是 undefined
p.x;//error, p 是一个空对象 undefined
window.x;//2

Point(1,1)函数在 var np=new Point(1,1)中的 this 在 "JavaScript this 决策树"中进行判定的过程是这样的:

1)var np=new Point(1,1)调用是用 new 进行调用的么?这个明显是,进入“是”分支,即 this 指向 np;

2)那么 this.x=1,即 np.x=1;

Point(2,2)函数在 var p= Point(2,2)中的 this 在 "JavaScript this 决策树"中进行判定的过程是这样的:

1)var p= Point(2,2)调用是用 new 进行调用的么?这个明显不是,进入“否”分支,即函数是否用 dot(.)进行调用?;

2)Point(2,2)函数不是用 dot(.)进行调用的?判定为否,即进入“否”分支,即这里的 this 指向全局变量 window,那么 this.x 实际上就是 window.x;

3)this.x=2 即 window.x=2.

最后看一下函数用 call 和 apply 进行调用的例子:

function Point(x, y){
    this.x = x;
    this.y = y;
    this.moveTo = function(x, y){
        this.x = x;
        this.y = y;
    }
}

var p1 = new Point(0, 0);
var p2 = {x: 0, y: 0};

p1.moveTo.apply(p2, [10, 10]);//apply 实际上为 p2.moveTo(10,10)
p2.x//10

p1.moveTo.apply(p2,[10,10])函数在 "JavaScript this决策树"中进行判定的过程是这样的:

我们知道,apply 和 call 这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。p1.moveTo.apply(p2,[10,10])实际上是p2.moveTo(10,10)。那么 p2.moveTo(10,10)可解释为:

1) p2.moveTo(10,10)函数调用是用 new 进行调用的么?这个明显不是,进入“否”分支,即函数是否用 dot(.)进行调用?

2)p2.moveTo(10,10)函数是用 dot(.)进行调用的,即进入“是”分支,即这里的this 指向 p2.moveTo(10,10)中.之前的对象 p2,所以 p2.x=10;

实例:

var name="The window";

var obj={
    name:'my object',
    getNameFunc:function(){
        alert(this.name);
        return function(){
            alert(this.name);
        }
    }
}

obj.getNameFunc()();

关于 JavaScript 函数执行环境的过程,IBM developerworks 文档库中的一段描述感觉很不错,摘抄如下:

“ JavaScript 中的函数既可以被当作普通函数执行,也可以作为对象的方法执行,这是导致 this 含义如此丰富的主要原因。一个函数被执行时,会创建一个执行环境(ExecutionContext),函数的所有的行为均发生在此执行环境中,构建该执行环境时,JavaScript 首先会创建 arguments 变量,其中包含调用函数时传入的参数。接下来创建作用域链。然后初始化变量,首先初始化函数的形参表,值为 arguments 变量中对应的值,如果 arguments 变量中没有对应值,则该形参初始化为 undefined。如果该函数中含有内部函数,则初始化这些内部函数。如果没有,继续初始化该函数内定义的局部变量,需要注意的是此时这些变量初始化为 undefined,其赋值操作在执行环境(ExecutionContext)创建成功后,函数执行时才会执行,这点对于我们理解 JavaScript中的变量作用域非常重要,鉴于篇幅,我们先不在这里讨论这个话题。最后为 this 变量赋值,如前所述,会根据函数调用方式的不同,赋给 this 全局对象,当前对象等。至此函数的执行环境(ExecutionContext)创建成功,函数开始逐行执行,所需变量均从之前构建好的执行环境(ExecutionContext)中读取。”

理解这段话对于理解 Javascript 函数将大有好处!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值