当前位置: 首页 > news >正文

初识JavaScript

JavaScript是动态弱类型解释型编程语言, JS解释器称为JS引擎为浏览器的一部分,常用于Web前端编程也可应用于服务端编程等场景.

Js使用单行注释//和多行注释'/*',*/两种注释符.

Js使用分号;或换行标志语句结束, 使用花括号{}标志代码块, 语义与缩进无关, 允许使用\进行折行.

Js标识符区分大小写,以字母或_, $开头, 后续字符可以为数字,字母或_, $.

Js的运算符与C基本一致, 保留了位运算符和取余%, 自增++,减--和复合赋值运算符.

Js赋值运算符返回右值, 因此允许连续赋值.

> f = function() {
    return  a = 1;
  };
> f()
1
> a = b = 1
1
> a
1
> b
1

因为弱类型的原因,JavaScript的关系运算符比较复杂:

  • == 等于: 值等于或隐式类型转换后等于

  • === 绝对等于: 类型相同且值相等

  • != 不等于, 与等于取值一定相反

  • !== 不绝对等于, 与绝对等于取值一定相反

示例:

> x = 233
233
> x == 233
true
> x == '233'
true
> x === 233
true
> x === '233'
false
> x != '233'
false
> x !== '233'
true
> null == undefined
true
> null === undefined
false

Js提供typeof()来判断对象类型:

> typeof('233')
"string"
> typeof(233)
"number"
> typeof([2,3,3])
"object"
> typeof({'name':'finley'})
"object"
> typeof(null)
"object"
> typeof(undefined)
"undefined"

开始学习JS的朋友可以在浏览器开发者工具的console中使用JavaScript进行交互式操作,或者在html的<script>元素中编写JavaScript脚本.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>First JavaScript</title>
</head>
<body>
    <script>
        var s = 'Hello World.';
        document.write(s);
    </script>
</body>
</html>

JavaScript 可以通过不同的方式来输出数据:

  • window.alert() 弹出对话框

  • document.write() 将内容书写到HTML文档中

  • console.log() 输出到浏览器控制台

JavaScript对象

JS使用var关键字声明变量,其数据类型包括:

  • 字符串(String)

  • 数字(Number)

  • 布尔(Boolean)

  • 数组(Array)

  • 对象(Object)

  • 日期(Date)

  • 空(Null)

  • 未定义(Undefined)

布尔型取值只有两个,用关键字truefalse表示。

示例(console):

> var a = 'hello'
> a
"hello"
> var b = "world"
> b
"world"
> var c = 1
> c
1
> var d = 1.0
> d
1
> var e = true
> e
true
> var f = null
> f
null

在Chrome的console下,可以不使用var关键字直接定义变量.

关键字null表示变量为空值, undefined表示值未定义.

Number

var x = new Number(123)

var x = 123

JS中只有一种数字类型, 可以带小数点也可以不带.数字不分为整数类型和浮点型类型,所有的数字都是浮点类型。JavaScript采用IEEE754标准定义的64位浮点格式表示数字.

当数字运算结果超过了JavaScript所能表示的数字上限,结果为正无穷大用关键字Infinity表示, 或负无穷大-Infinity.

NaN表示非数字对象, isNaN(val)可以检查一个对象是否为NaN.

示例:

> x = 1 / 'a'
NaN
> isNaN(x)
true
> x = 1 / 0
Infinity
> isNaN(x)
false

Array

var a = new Array(1, 2, 3, 4)

var a = [1, 2, 3, 4]

数组(Array)用于顺序存储元素,下标由0开始:

> a = [1,2,3]
[1, 2, 3]
> a[0]
1
> a[1] = "h"
"h"
> a
[1, "h", 3]

常用方法:

  • length 数组长度, 注意length是一个属性不是方法

  • indexOf(index) 返回某位置上的元素

  • slice(lower, upper) 数组切片, 返回[lower, upper)之间的元素.

  • splice(start, len, item1, item2, ...) 修改数组,可以用于删除,插入元素

  • pop() 删除数组的最后一个元素并返回删除的元素

  • push(val) 向数组的末尾添加一个或更多元素,并返回新的长度

  • unshift(val) 向数组的开头添加一个或更多元素,并返回新的长度

  • toString() 把数组转换为字符串,并返回结果

  • sort(func) 对数组的元素进行排序

splice示例:

> a = [1, 2, 3, 4]
[1, 2, 3, 4]
> a.splice(0, 1) //删除从0开始1个元素, 返回被删除的内容
[1]
> a
[2, 3, 4]
> a.splice(0,2, "a", "b") //插入元素, 返回被替换的内容
[2, 3]
> a
["a", "b", 4]

sort示例:

> a = [2, 3, 1, 4]
[2, 3, 1, 4]
> a.sort()
[1, 2, 3, 4]
> a
[1, 2, 3, 4]
> a.sort(function(x,y){return y-x})
[4, 3, 2, 1]
> a
[4, 3, 2, 1]

String

var s = new String('hello')

var s = 'hello'

var s = "hello"

字符串字面值可以使用单引号对或双引号对包围.

String对象可以使用[]访问元素.

常用方法:

  • length 长度

  • indexOf(pattern) 定位字符串中某子串首次出现的位置, 不存在返回-1

  • search(re) 正则表达式匹配

  • match(pattern) 函数用来查找字符串中特定的字符串,若存在则返回这个子串,否则返回null

  • toUpperCase() / toLowerCase() 大小写转换

  • replace(pattern, target) 替换子串

  • slice() 切片

  • substr(start,length) 返回start开始长为length的一段子串, 包含start.如果start为负数,则start=str.length+start;如果 length 为 0 ,负数或未指定,将返回一个空字符串。

  • substring(start,end) 返回指定位置[start, end)一段子串

  • spilt() 分割为数组

+可以用于字符串连接, 甚至可以用于String与Number连接.

y="Hello "+"World";
"Hello World"
y = "Hello " + 233
"Hello 233"

Object

JavaScript中几乎一切都是对象.

>var user = {usernmame:'finley', password:'1234'}
>user
Object {usernmame: "finley", password: "1234"}
> user.usernmame
"finley"

对象也可以作为字典来使用:

> var user = {'username':'finley', 'password':'1234'}
> user['username']
> user['password'] = 'abcd'

成员可以动态添加:

> user.email = "finley@233.com"
"finley@233.com"
> user
Object {usernmame: "finley", password: "1234", email: "finley@233.com"}

JavaScript中函数也是对象, 同样可以作为成员.

> user.login = function() { return 'login'};
function() { return 'login'}
>user.login()
"login"

for-in循环可以遍历Object:

> for (item in user) {console.log(item)};
usernmame
password
email
login

更多关于对象的内容将在面向对象编程中介绍.

流程控制

if

示例:

if (time > 20) {
    console.log('good evening') 
}
else if (time > 12) {
    console.log('good afternoon')
}
else {
    console.log('good morning')
}

switch

示例:

var d = new Date().getDay();
switch (d) {
case 0:
    x = "Sunday";
    break;
case 1:
    x = "Monday";
    break;
case 2:
    x = "Tuesday";
    break;
case 3:
    x = "Wednesday";
    break;
case 4:
    x = "Thursday";
    break;
case 5:
    x = "Friday";
    break;
case 6:
    x = "Saturday";
    break;
}

for

for(var i = 1, s = 0; i < 101; i++) {
    s += i
}

for-in

for-in循环可以用来遍历Array, Sting和Object.

遍历String时注意i为下标.

var arr = [1, 2, 3, 4, 5]
for (var i in arr) {
    document.write(i + ' ')
}

var s = 'helloworld'
for (var i in s) { // i is index
    document.write(s[i] + ' ')
}

var user = {usernmame:'finley', password:'1234'}
for (item in user) {
    document.write(item + ' ')
};

while

var i = 0;
while (i < 5) {
    i++;
}
document.write(i)

var i = 0;
do {
    i++;
} while(i < 5);
document.write(i)

break / continue

break 语句用于跳出循环

continue 用于跳过循环中的一次迭代

函数与闭包

函数

function 关键字可以定义函数:

> function func(a) {return a;}
func(a) {return a;}
> func(1)
1

或者定义匿名函数:

> f = function (a) {return a;}
function(a) {return a;}
> f(1)
1

Js中函数也是对象, 拥有属性并可以进行拷贝和传递.

> typeof(f)
"function"

函数的参数传递和返回,均采用浅拷贝传递.

即只拷贝对象本身,成员中指向的其它对象不进行拷贝.

示例1:

> f = function (a) {a = 1}
function(a) {a = 1}
> a = 2
2
> f(a)
undefined
> a
2

示例2:

> f = function (a) {a[0]=1; a.n = 1}
function(a) {a[0]=1; a.n = 1}
> a = [2, 3, 4, 5]
[2, 3, 4, 5]
> f(a)
undefined
> a
[1, 3, 4, 5]
> a.n
1

函数可以嵌套定义, Js作用域是链式的内部作用域可以访问外部作用域的对象.

    function outer() {
        var tmp = 233;
        function add() { tmp++; return tmp;}
        return add;
    }
    > a = outer()
    function add() { tmp++; return tmp;}
    > a()
    234
    > a()
    235

若参数未被赋值则为undefined:

> f = function (a) {return a;}
function(a) {return a;}
> f()
undefined

可以用这个特性实现默认参数:

f = function (a) {
    if (a === undefined) {
        a = 0;
    }
    return a;
}

> f()
0

函数对象中的arguments属性是一个保存了所有参数的数组.

function findMax() {
    var i, m = 0;
    for (i in arguments) {
        if (arguments[i] > m) {
            m = arguments[i];
        }
    }
    return m;
}
> findMax(1,555,233,666)
666

这个示例也展示了如何使用可变参数.

因为函数也是对象这一特性, Js提供了callapply两个函数进行调用.

> f = function(a,b) {return [a,b]}
> f.call(f, 1,2)
[1, 2]
> f.apply(f, [1,2])
[1, 2]

闭包

先看一个示例:

function outer() {
    var tmp = 233;
    function inner() { return tmp;}
    return inner;
}

var c = outer();
document.write(c());  // c = 233

因为Js的链式作用域机制, 内部作用域可以访问外部作用域的对象, 但外部作用域无法访问内部作用域.

示例中通过返回的inner()函数可以在外部访问outer()的作用域.

inner()函数就是outer()函数的闭包.

闭包除了在外部访问作用域外另一个作用是使得局部变量始终保存在内存中.

将上述示例做一些修改:

    function outer() {
        var tmp = 233;
        function add() { tmp++; return tmp;}
        return add;
    }
    > a = outer()
    function add() { tmp++; return tmp;}
    > a()
    234
    > a()
    235

可以看出局部变量tmp没有被回收.

学习Javascript闭包 - 阮一峰的网络日志

面向对象

对象

JavaScript中没有类,但是其一切都是对象.

在数据类型一节中,我们把对象当做字典来认识, 介绍了对象的成员(属性和方法)以及它们的动态特性.

JavaScript支持new运算符:

function User(username, password) {
    this.username = username;
    this.password = password;
}

user = new User('finley', '1234');
document.write(user.username, user.password);

因为没有类, new运算符调用了相应的函数作为构造器.

同样因为没有类, 所以JavaScript无法使用构造函数创建类属性.

this

this是JavaScript关键字, 在函数调用时代表调用函数的对象.

对于全局性调用, this代表的全局对象Global.

var x = 1;
function func() {
    this.x = 0;
}
func();
document.write(x);  // output: 0

我们通常var关键字声明变量, 但是直接给未声明的对象赋值一般也不会引起错误.

实际上,直接向未声明对象赋值等同于给this对象下添加并初始化同名成员:

x = 0; // 等价于this.x = 0;

对于对象方法调用, this代表代表调用的对象:

var obj = {};
obj.x = 1;
obj.func = function() {
    this.x = 0;
};
obj.func();
document.write(obj.x);  // output: 0

apply和call函数用于改变调用函数的对象, 即改变了函数调用的上下文:

var obj = {};
var another = {};
obj.x = 1;
another.x = 0;
obj.func = function() {
    document.write(this.x)
};
obj.func.call(another);  // output: 0

call和apply的区别在于, call使用可变参数传参, apply使用数组传参:

var obj = {};
obj.add = function(x, y) {
    return x + y;
};

obj.add.call(obj, 1,1);

obj.add.apply(obj, [1,1]);

prototype

原型链系统是JS中代替传统继承系统的方案, 具有非常强的动态特性.

JavaScript中所有Object均拥有一个prototype属性, 将需要和派生类共享的成员写在prototype下, 私有的成员添加到Object中.

派生类继承基类的prototype属性, 构成链状结构称为原型链.

// 基类构造器
function User(username) {
    this.username = username;
}

// 基类方法
User.prototype.hello = function() {
    document.write('I am ' + this.username + '<br>');
};

// 派生类构造器
function Student(username, school) {
    // this对象调用基类构造器, 进行基类构造
    User.apply(this, arguments);
    // 添加新增成员
    this.school = school;
}

// 用基类prototype构造派生类的prototype
Student.prototype = Object.create(User.prototype);

//重写方法
Student.prototype.hello = function() {
    document.write('I am ' + this.username + ' ,and I am a student.<br>');
};

// 新增方法
Student.prototype.enroll = function() {
    document.write(this.username + ' enrolled  in ' + this.school );
};

// 实例化
var user = new User('finley');
var student = new Student('finley', 'unknown');

// 测试
user.hello();
student.hello();
student.enroll();

上述示例展示了如何通过原型链继承并重写成员.

更多关于原型链的说明请参见:

构造函数的继承 - 阮一峰的网络日志

非构造函数的继承 - 阮一峰的网络日志

面向对象编程 - MDN

继承与原型链 - MDN

模块

JavaScript的模块机制基于对象.

module.exports属性指定了模块的公开对象,其它模块导入该模块时实际上是导入了这个对象.

require(path)函数用于导入其它模块,参数指定要导入模块的路径,并返回目标模块的公开对象.

module.exports = config;

var config = require("./config.js");

相关文章:

  • iOS: 如何调节UITabbarItem的图片和文字位置
  • Python学习笔记——文件写入和读取
  • C/C++动态分配与释放内存的区别详细解析
  • I.MX6 简单电路模拟USB设备的插入
  • MySQL备份 博客---MYSQLDBA 黄杉
  • java-工具-Webservice wsdl解析
  • 重定向 管道
  • [ZigBee] 16、Zigbee协议栈应用(二)——基于OSAL的无线控制LED闪烁分析(下)
  • 微信公众号开发小记——5.python微信红包
  • Android 开发之布局细节对比:Gravity相关
  • 纯Html+Ajax和JSP两者对比的个人理解
  • LEAVE LIST-PROCESSING和LEAVE TO LIST-PROCESSING事件的作用
  • 开根号研究
  • CCIE学习笔记 ----BGP
  • 什么是内存泄漏
  • 《Java编程思想》读书笔记-对象导论
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 2017前端实习生面试总结
  • 77. Combinations
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • flask接收请求并推入栈
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • HTTP中GET与POST的区别 99%的错误认识
  • JavaScript 奇技淫巧
  • javascript 总结(常用工具类的封装)
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Mysql数据库的条件查询语句
  • nfs客户端进程变D,延伸linux的lock
  • PAT A1120
  • uni-app项目数字滚动
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 诡异!React stopPropagation失灵
  • 精彩代码 vue.js
  • 学习HTTP相关知识笔记
  • k8s使用glusterfs实现动态持久化存储
  • 阿里云API、SDK和CLI应用实践方案
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (4.10~4.16)
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (十八)三元表达式和列表解析
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (一)基于IDEA的JAVA基础1
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)编辑寄语:因为爱心,所以美丽
  • ***利用Ms05002溢出找“肉鸡
  • *上位机的定义
  • .NET Core 成都线下面基会拉开序幕
  • .net/c# memcached 获取所有缓存键(keys)
  • .net开发时的诡异问题,button的onclick事件无效