面向Android的快速学习JavaScript笔记(基础篇 上)

JavaScript基础学习

这篇文章是我自己在学习廖雪峰大神的JavaScript教程关于JavaScript的总结,后续会补上全部的总结笔记。
主要用于我自己日后的快速回顾检索重点知识用的。
结合自身,这篇笔记对于有JavaSE基础的人来说,可以达到极速入门JavaScript的效果(毕竟java和JavaScript有很多相似的地方)
笔记对于重复的部分不做描述,重点放在JS的特性上,所以也命名为面向Android的JS学习
如有理解错误的地方,希望大家可以踊跃指出,我立即修改

@(JavaScript)


目录

  • 数据类型
    • 字符串
    • 数组
    • 对象
    • 条件判断
    • 循环
    • 集合
  • 函数
    • 定义
    • 调用
    • argument
    • rest
    • return
    • 变量作用域
      • 局部作用域
      • 变量提升
      • 全局作用域
      • 命名空间
      • 常量
    • 方法
      • this
      • apply 和 call

数据类型

  • number
    • 基本:整数,浮点数,科学计数法,负数
    • NaN : not a number,只能用isNaN()来判断
    • Infinity : 表示无限大,超过了Number所能表示的最大值
  • 字符串
  • 布尔值
  • null
  • undefined
    • Number String Null Undefined Boolean 是JS的基本数据类型
  • 数组
    • 直接赋值会自动填充如:arr[10],缺省的部分自动填充undefined
  • 比较运算符
    • 使用===代替==,==会自动转换类型,而===不会自动转换
    • 运算符顺序:算术运算符 > 比较运算符 > 逻辑运算符 > 赋值运算符
  • 对象
  • 变量
    • 动态编译,所以全部指定为var, 不指定就为全局变量

字符串

  • 换行:\n, 或者直接换行(在ES6才能直接使用)
  • 拼接: + 或者 var name = 'hello'; ${name}
  • 操作:
    • str.length
    • str[num] , 不能直接通过下标修改字符串
    • toUpperCase() 大写转换
    • toLowerCase() 小写转换
    • indexOf() 检索
    • substring() 截取

数组

  • 常规属性不做描述了,数组大小是动态改变

var arr = [1, 'hello', 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 'hello', 3, undefined, undefined, undefined]
arr[7] = 4;
arr; // arr变为[1, 'hello', 3, undefined, undefined, undefined, undefined, 4]
arr.length = 2;
arr; // arr变为[1, 'hello']
  • indexOf() 检索
  • slice() 等于 substring() 截取
  • push() 和 pop() 参考队列使用,入队和出队
  • unshift() 和 shift() 头部的 入队 和 出队
  • sort() 排序 ,number自动转换成String,String按照ASCII排序
  • reverse() 反转
  • splice() 万能方法:
    • splice()方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
  • concat() 拼接字符串
  • join() 使数组每个字符串用指定字符串连接
    • 如果Array的元素不是字符串,将自动转换为字符串后再连接。
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'

对象

  • JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成
    • 键值对: 属性:属性名
    • 属性使用:
 var xiaohong = {
    name: '小红',
    'middle-school': 'No.1 Middle School'
};
//属性使用
xiaohong['middle-school']; // 'No.1 Middle School'
xiaohong['name']; // '小红'
xiaohong.name; // '小红'
  • JavaScript对象是动态类型,所以可以动态添加属性
    • bean.age=18; // 这样属性就添加成功了
    • delete bean.age ; // 删除属性成功
  • in字符检测 对象是否包含属性
    • age in bean // true or false

条件判断

JS中的if...else...的使用和Java基本一样

  • 如果不加{}使用的话, if...else...只能作用他下面的第一行
var age = 20;
if (age >= 18)
    alert('adult');
else
    console.log('age < 18'); // 添加一行日志
    alert('teenager'); // <- 这行语句已经不在else的控制范围了
  • 在if..else if...else...的多行条件判断下,前面满足条件就不会执行后面的情况了

循环

  • for循环

var x = 0;
var i;
for (i=1; i<=100; i++) {
    x = x + i;
}
x; // 5050

1: i = 1; 初始条件,执行一次
2:i <=100 ; 判断条件 ,不满足就退出循环
3: x = x+i ; 具体循环的业务逻辑
4: x++;  每次循环的递增条件

!!所以循环的顺序是  
1 > 2 > 3 > 4 > 2 > 3 > 4  > 2 ...... > 2(不满足条件 ,退出循环)  
  • for...in (比较像Java的foreach)
    • 遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。
    • 对 对象遍历
var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};
for (var key in o) {
    if (o.hasOwnProperty(key)) { //判断是否包含KEY
        alert(key); // 'name', 'age', 'city'
    }
}
  • 对数组遍历(遍历 得到的是String而不是number)
var a = ['A', 'B', 'C'];
for (var i in a) {
    alert(i); // '0', '1', '2'
    alert(a[i]); // 'A', 'B', 'C'
}
  • while 和 do..while (和Java基本一样这里不赘述了)

集合

是在ES6以后才引入的

  • Map :优点查询快,无论集合多大,检索速度基本不变

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);

m.get('Michael'); // 95
m.set('Tom',65);  //动态设置, 一个key只能对应一个值,
m.has('Tom');  //是否存在KEY, 返回 布尔值
m.delete('Adam');  //删除
  • Set :只储存key,不储存value,同时会把 重复的key自动过滤
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
s.add(3);
s; // Set {1, 2, 3, "3"}
s.delete(3);
s; // Set {1, 2, "3"}
  • iterable
    • for...of :用法本身跟for...in一样,但是却修复了如下问题
    var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    alert(x); // '0', '1', '2', 'name'
}

for (var x of a) {
    alert(x); // 'A', 'B', 'C'
}
  • foreach :
    • 对于set因为没有value,所以下面的element和index是 一致的
    • JS中对于参数可以不一致,所以是可以只穿一个自己需要的参数
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    alert(element);
});

a.forEach(function (element) {
    alert(element);
});

函数

定义

  • 正常定义

function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

function 指出这是一个函数定义;
abs 是函数的名称;
(x) 括号内列出函数的参数,多个参数以,分隔;
{ ... } 之间的代码是函数体,可以包含若干语句,甚至可以没有任何语句。
return 返回值,可以没有:返回undefined
  • 匿名定义
 var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};
与正常定义完全等价,值已经赋给abs了
注意别忘了最后的 ' ; '

调用

  • 传参 :
    • 可以传多个参数,不过只会使用前面有效的
    • 也可以不传,就等于传入了undefined
function abs(x) {
    //控制传入参数类型
    if (typeof x !== 'number') {
        throw 'Not a number';
    }
  ...
}

argument

  • 定义:关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array
  • 使用:利用arguments,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值
  • 常用于判断传入参数的个数
function abs() {
    if (arguments.length === 0) {
        return 0;
    }
    var x = arguments[0];
    return x >= 0 ? x : -x;
}

abs(); // 0
abs(10); // 10
abs(-9); // 9

rest

  • 定义:ES6中引入的关键字rest,表示获取定义参数以外的参数
function foo(a, b, ...rest) {
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
}

foo(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]

foo(1);
// 结果:
// a = 1
// b = undefined
// Array []

return

  • 由于JavaScript引擎在行末自动添加分号的机制,所以代码如下:
function foo() {
    return; // 自动添加了分号,相当于return undefined;
        { name: 'foo' }; // 这行语句已经没法执行到了
}

应改为
function foo() {
    return { // 这里不会自动加分号,因为{表示语句尚未结束
        name: 'foo'
    };
}

变量作用域

局部作用域:

  • 在函数内定义的变量
  • 这个和java比较相似,就是优先使用最靠近的{}里面的变量
  • 不同的是,for循环中无法定义局部作用域的变量
    所以在ES6中引入了 let,就可以在for中定义了,如下:
function foo() {
    for (var i=0; i<100; i++) {
        //
    }
    i += 100; // 仍然可以引用变量i
}

function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
        sum += i;
    }
    i += 1; // 还没定义无法使用,报错
}

变量提升

  • 先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部
function foo() {
    var x = 'Hello, ' + y;
    alert(x);
    var y = 'Bob';
}


//这样的代码实际上在JavaScript眼中是这样的

function foo() {
    var y; // 提升变量y的申明
    var x = 'Hello, ' + y;
    alert(x);
    y = 'Bob';
}

全局作用域

  • 不在函数内定义的变量就是全局的
  • JavaScript默认有一个全局对象window,全局变量都是绑定在window上的一个属性
  • 函数实际也是一个全局变量
var course = 'Learn JavaScript';
alert(course); // 'Learn JavaScript'
alert(window.course); // 'Learn JavaScript'

function foo() {
    alert('foo');
}

foo(); // 直接调用foo()
window.foo(); // 通过window.foo()调用,一样的效果

命名空间

  • 由来:因为全局变量都绑定在 window上,当不同JS文件 使用了相同的变量就会产生冲突
  • 解决:将变量绑定到一个全局变量中
// 唯一的全局变量MYAPP:
var MYAPP = {};

// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函数:
MYAPP.foo = function () {
    return 'foo';
};

常量

  • ES6中引入const关键字表示常量
  • let相同,同时块级作用域

方法

  • 一个对象中绑定函数,成为这个对象的方法

this

  • 特殊变量,始终指向当前对象
  • this指向的问题:
function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 25, 正常结果
getAge(); // NaN

var fn = xiaoming.age; // 先拿到xiaoming的age函数
fn(); // NaN

造成上面的原因:this指向动态改变,当在全局调用的时候this就指向了window,显然window没有birth属性。
解决办法:始终 使用 正确对象 . 方法(属性 )

  • 关键:函数内定义函数
var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        function getAgeFromBirth() {
            var y = new Date().getFullYear();
            return y - this.birth;
        }
        return getAgeFromBirth();
    }
};
xiaoming.age();  //Uncaught TypeError: Cannot read property 'birth' of undefined

//原因:this指向的匿名函数内部也不存在birth
//解决办法:捕获this
age: function () {
        var that = this; // 在方法内部一开始就捕获this
        function getAgeFromBirth() {
            var y = new Date().getFullYear();
            return y - that.birth; // 用that而不是this
        }
        return getAgeFromBirth();
    } 

apply 和 call

  • 用于控制this的指向
  • apply(this指向对象,参数数组)
  • call(this指向对象,参数1,参数2.......)
  • 用法:
function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
getAge.call(xiaoming,null); 
  • apply的应用:装饰器:
var count = 0;
var oldParseInt = parseInt; // 保存原函数

window.parseInt = function () {
    count += 1;
    return oldParseInt.apply(null, arguments); // 调用原函数
};

// 测试:
parseInt('10');
parseInt('20');
parseInt('30');
count; // 3

最后:
第一部分的基础快速学习笔记就到这里,如果需要带目录的MD格式笔记可以私信我或者评论,我都可以发给你
如果觉得有那么一点帮助的朋友可以点一下赞鼓励一下
后续进阶部分学习笔记,我会尽快补充上的

你可能感兴趣的:(面向Android的快速学习JavaScript笔记(基础篇 上))