美文网首页
老司机Studio 第五章

老司机Studio 第五章

作者: cenkai88 | 来源:发表于2017-09-03 01:47 被阅读39次

高级函数

  • sort函数
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x < y) {
        return 1; // 返回1代表需要位置互换
    }
    if (x > y) {
        return -1; // 返回-1代表不需要互换
    }
    return 0;
}); // [20, 10, 2, 1]
  • filter函数
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
    console.log(element); // 依次打印'A', 'B', 'C'
    console.log(index); // 依次打印0, 1, 2
    console.log(self); // self就是变量arr
    return true;
});

var arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
var r = arr.filter(function (element, index, self) {
    return self.indexOf(element) === index; // indexOf函数获取array中某个元素的下标
});

作用域

在JavaScript中,我们可以将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找。
这里的标识符,指的是变量名或者函数名。

作用域与执行上下文是完全不同的两个概念。
JavaScript代码的整个执行过程,分为两个阶段:

代码编译阶段与代码执行阶段
编译阶段由编译器完成,将代码翻译成可执行代码,这个阶段作用域规则会确定,对于函数,是函数的定义过程。
执行阶段由引擎完成,主要任务是执行可执行代码,执行上下文在这个阶段创建,是函数的调用过程。

function a(){ //函数定义
  console.log(1);
}
a() //函数调用
编译与执行

执行上下文

执行上下文(Execution Context)。
每次当控制器转到可执行代码的时候,就会进入一个执行上下文。执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。
全局环境:JavaScript代码运行起来会首先进入该环境
函数环境:当函数被调用执行时,会进入当前函数中执行代码

var color = 'blue';

function changeColor() {
    var anotherColor = 'red';

    function swapColors() {
        var tempColor = anotherColor;
        anotherColor = color;
        color = tempColor;
    }

    swapColors();
}

changeColor();
第一步:全局上下文入栈 第二步:changeColor的执行上下文入栈 第三步:swapColors的执行上下文入栈 第四步:swapColors的执行上下文出栈 第五步:changeColor的执行上下文出栈 整个过程

函数定义阶段——闭包

作用域链:是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。

var a = 20;

function test() { // 执行上下文A
    var b = a + 10;

    function innerTest() { // 函数B
        var c = 10;
        return b + c;
    }

    return innerTest();
}

test();
作用域链

闭包:设有函数B是在执行上下文A内定义的。如果B内部访问了A内的变量对象,则产生闭包。
闭包的重要特点是,执行上下文A出栈后不会被内存回收,也就是说B依然可以访问到原来定义时的数据。�

var fn = null;
function foo() {
    var a = 2;
    var c = 100;
    function innnerFoo() { 
        // console.log(c); // 在这里,试图访问函数bar中的c变量,会抛出错误
        console.log(a);
    }
    fn = innnerFoo; // 将 innnerFoo的引用,赋值给全局变量中的fn
}

function bar() {
    var c = 100;
    fn(); // 此处的保留的innerFoo的引用
}

foo();
bar();
在chrome中观察闭包

函数执行阶段——变量对象

执行上下文的创建

变量对象的创建过程:
变量对象的创建,依次经历了以下几个过程。

  1. 建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。
function test(x,y){
  console.log(arguments);
  console.log(x);
  console.log(y);
}
test(1,2);
  1. 检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖

  2. 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

image.png
// demo1
function foo() { console.log('function foo') }
var foo = 20;
console.log(foo); // 20

console.log(foo); // function foo
function foo() { console.log('function foo') }
var foo = 20;
// demo2
function test() {
    console.log(a);
    console.log(foo());
    
    var a = 1;
    function foo() {
        return 2;
    }
}
test();

// demo3
function test() {
    console.log(foo);
    console.log(bar);
    var foo = 'Hello';
    console.log(foo);
    var bar = function () { // 函数的赋值
        return 'world';
    }

    function foo() { // 函数的声明
        return 'hello';
    }
}
test();

var/let/const
var 声明的变量在当前函数内一直存在。
function (){
...生效...
}
let / const 声明的变量只在当前代码块
({}包裹起来的为一个代码块,但不是只有{}产生代码块,如if后可以没有{}的情形)
中存在,前者为变量,后者为常量(ES6)。

function test(){
  {
    let a = 1;
    var b = 1
  }
console.log(b)
console.log(a)
}

延时执行,定时执行

  • setTimeout
for(var i = 0; i<5; i++){
  setTimeout(function(){
    console.log(i)
  }, i*1000)
}
// 5 5 5 5 5

for (var i=1; i<=5;  i++) { 
    setTimeout((function(i) {
        return function() {
            console.log(i);
        }
    })(i), i*1000 );
}
// 0 1 2 3 4

for(let i = 0; i<5;i++){
  setTimeout(function(){
    console.log(i)
  }, i*1000)
}
// 0 1 2 3 4
  • setTimeInterval
  • clearTimeInterval

操作DOM

  • innerHTML
  • innerText
  • style
  • appendChild
<p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>
var js = document.getElementById('js'),
list = document.getElementById('list');
list.appendChild(js);
  • document.createElement
  • insertBefore(newElement, referenceElement)
  • removeChild

作业

  1. 写出“函数执行阶段——变量对象”这一节的demo3的执行顺序。
  2. 使用原生javascript实现一个to-do list


    to-do List

相关文章

  • 老司机Studio 第五章

    高级函数 sort函数 filter函数 作用域 在JavaScript中,我们可以将作用域定义为一套规则,这套规...

  • Android Studio导入Module步骤

    Android Studio导入Module(老司机忽略):首先:File----New----Import Mo...

  • 老司机Studio课程大纲

    1 前端开发中的基本概念2 CSS3 基本特性3 CSS3 进阶特性4 原生JavaScript5 JQuery的...

  • 老司机Studio 第二章

    CSS3的基本特性 一切的基础:选择器 基本选择器:div (选中所有div标签).test (class="te...

  • APK Signature Scheme v2

    背景知识 老司机要开车了,你准备好了吗?Android Studio 2.2 最近发布了许多新增功能和改进功能(详...

  • 老司机带老司机

    现在工作不好找,特别是我这个70后,年龄问题成了我应聘的弊端。 年前考交通运输上岗证的同学群因为过年加疫情,沉默好...

  • 老司机Studio 第一章

    前端开发中的基本概念 前端开发者可以做什么 后台管理系统 移动端SPA H5宣传页 微信小程序 node.js(后...

  • 老司机Studio 第三章

    CSS3的进阶特性 verticle-align垂直对齐方式只对容器内的inline-block元素起作用:图片,...

  • 老司机Studio 第四章

    Javascript初步 Javascript基本概念 Javascript 是 ECMAScript标准的一种实...

  • 老司机Studio 第六章

    // demo1 // demo2 // demo3 jquery jquery简单来讲就是一系列原生接口的封装,...

网友评论

      本文标题:老司机Studio 第五章

      本文链接:https://www.haomeiwen.com/subject/xvrdjxtx.html