JavaScript学习笔记

1、什么是JavaScript?

1.1、简介:

​ JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式、声明式、函数式编程范式。 1995年 Netscape 发明了 JavaScript。


2、基础语法

2.1 打印信息

打印日志

console.log('xxx');

2.2 变量数据类型

定义变量

​ Es6以前:

全局变量
{
    var x = 1;
}
// 这里可以使用 x 变量

for (var i = 0; i < 10; i++) {
    // 一些代码...
}
// 这里输出 i 为 10 (不安全)

​ ES2015(ES6) 新增加了两个重要的javaScript 关键字: let 和 const:

// 使用 let
let x = 2;       // 全局作用域

let 声明的变量只在 let 命令所在的代码块内有效。
{
    let x = 1;//推荐使用 
}
// 这里不可以使用 x 变量

定义常数
//用const定义添加后不可以更改其值,const 声明的常量必须初始化:
const PI = 3.141592653589793;
PI = 3.14;      // 报错
PI = PI + 10;   // 报错

​ 注意:为了防止JavaScript的变量污染,为了修补JavaScript这一严重设计缺陷,ECMA在后续规范中推出了strict模式,在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。

启用strict模式的方法是在JavaScript代码的第一行写上:

'use strict';

数据类型

number JavaScript不区分整数和浮点数,统一用Number表示

var i = 1;
var f = 1.1

字符串

var str = 'August' //字符串
var str = "Crazy" //字符串

布尔值

true
false

null和undefined

null表示一个“空”的值,它和0以及空字符串''不同,0是一个数值,''表示长度为0的字符串,而null表示“空”。而undefined表示值未定义。

数组

//定义一个数组
var array = [1, 2, 3.14, 'Hello', null, true];

//另一种创建数组的方法是通过创建对象的Array()方法函数实现:
new Array(1, 2, 3); // 创建了数组[1, 2, 3]

对象

​ JavaScript的对象是一组由键-值组成的无序集合(类似于python的字典),例如:

JavaScript对象的键都是字符串类型,值可以是任意数据类型。每个属性值后面要用,号,最后一个不需要.

var person = {
	name:"xiaoming",
	age : 18,
    tags: ['js', 'web', 'mobile'],
    hasCar: true,
    zipcode: null
};

3、运算符

3.1、算数运算符

与C语言几乎一致

+ - * / %

1 + 2; // 3
(1 + 2) * 5 / 2; // 7.5
2 / 0; // Infinity  无穷大
0 / 0; // NaN
10 % 3; // 1
10.5 % 3; // 1.5

3.2、比较运算符号

> < == === >= <=

注意:第一种是 == 比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;(不推荐使用)

​ 第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再进行比较(数字通常用此方法)

由于JavaScript这个设计缺陷,不要使用==比较,始终坚持使用===比较。

另一个例外是NaN这个特殊的 Number与所有其他值都不相等,包括它自己:

NaN === NaN; // false

//唯一能判断NaN的方法是通过isNaN()函数:
isNaN(NaN); // true

//最后要注意浮点数的相等比较:
1 / 3 === (1 - 2 / 3); // false (比较时候尽量避免浮点数进行数据比较)
//要比较两个浮点数是否相等,只能计算它们之差的绝对值,看是否小于某个阈值:
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true

4、函数

4.1、函数的定义和使用

定义函数使用关键字 function

//方法一:
//函数名 abs , 参数 x   
function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};
//方法二:
//实质是建立匿名函数赋值变量接收
var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};
//由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数:
abs(10, 'hello'); // 返回10
abs(-9, 'hello', 'world', null); // 返回9

//传入的参数比定义的少也没有问题,参数x将收到undefined,计算结果为NaN。
abs(); // 返回NaN

//要避免收到undefined,可以对参数进行检查
function abs(x) {
    if (typeof x !== 'number') {
        throw 'Not a number';  //手动抛出异常
    }
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

​ 函数没有return返回值时,函数执行完毕后也会返回结果,只是结果为undefined

argument对象关键字

它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似数组但它不是一个数组


function fun(x) {
    console.log('x = ' + x); // 10
    console.log('arguments.length = ' + arguments.length);
    for (let i=0; i<arguments.arguments.length = 3; i++) {
        console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
    }
}
fun(10, 20, 30);
//	  x =  10
//    arguments.length = 3
//    arg 0 = 10
//    arg 1 = 20
//    arg 2 = 30
//    undefined    <---arguments[3] 



image-20210813174044220

​ 利用arguments,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值.

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 []   注意不是undefined,rest参数会接收一个空数组

rest参数只能写在最后,前面用...标识,从运行结果可知,传入的参数先绑定ab,多余的参数以数组形式交给变量rest,所以,不再需要arguments我们就获取了全部参数。

最后要注意:

​ 由于JavaScript引擎有一个在行末**自动添加 ; (分号)**的机制

function fun() {
    return
        { name: '小明' };
}

fun(); // undefined


//等价于
function fun() {
    return;	// 自动添加了分号,相当于return undefined;
        { name: '小明' };  //后面的函数根本不会执行
}
fun(); // undefined

​ 改进方法:可以在return后面加一对大括号{},表示语句还没有结束

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

4.2、this指向

​ 它拥有不同的值,具体取决于它的使用位置:

  • 在方法中,this 指的是所有者对象。
  • 单独的情况下,this 指的是全局对象。
  • 在函数中,this 指的是全局对象。
  • 在函数中,严格模式下,this 是undefined
  • 在事件中,this 指的是接收事件的元素。

call()apply() 这样的方法可以将 this 引用到任何对象。


bind()、call()apply()三个方法的对比

image-20210813211951241

参数: this 的指向对象 第二至之后直接放进去

call(obj,x,x,x) obj.myFun.call(obj,‘成都’, … ,‘string’ )

参数: this 的指向对象 第二至之后需要数组放进去

apply(obj,[x,x,x])obj.myFun.apply(obj,[‘成都’, …, ‘string’ ])

参数: this 的指向对象 第二至之后需要数组放进去

bind(obj)(x,x,x) obj.myFun.call(obj,‘成都’, … ,‘string’ )()

bind 返回的是一个新的函数,你必须调用它才会被执行,所以应该在bind()方法后面多了个 ()来调用

​ 当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

4.3、class类继承

​ 新的关键字class从ES6开始正式被引入到JavaScript中。class的目的就是让定义类更简单。

function Student(name) {
   this.name = name;
}
Student.prototype.hello = function () { //hello指向Student原型
	alert('Hello, ' + this.name + '!');
}
var xiaoming = new Student('小明');//创建对象
xiaoming.hello();

image-20210813230132629

若用class来写Student可以这样

class Student {
   //构造器
   constructor(name) {
      this.name = name;
	}
   hello() {
          alert('Hello, ' + this.name + '!');
	}
}
var xiaoming = new Student('xaioming');
xiaoming.hello();

image-20210813230256025


class的定义包含了构造函数constructor和定义在原型对象上的函数hello()(注意没有function关键字),这样就避免了Student.prototype.hello = function () {...}这样分散的代码。

class继承

​ 直接通过extends来实现:

class Student {
    //构造器
    constructor(name) {
        this.name = name;
    }
    hello() {
        console.log('Hello, ' + this.name + '!');
    }
}
//Student2类 继承 Student类
class Student2 extends Student {
    constructor(name, age) {
        super(name); //需要super调用父类的构造方法!
        this.age = age;
    }
    myage() {
        console.log('Hello, myage ' + this.age + '!')
    }

}
var myAge = new Student2('小红', 20);
myAge.hello();//继承的hello方法
myAge.myage();

image-20210813231748180

​ 注意:在子类中要加入构造器constructor并记得用super调用父类的构造方法,类似于Java.


5、浏览器对象

浏览器对象模型(Browser Object Model (BOM)).

window对象,浏览器都支持 window 对象。它代表浏览器的窗口。

  • 所有全局 JavaScript 对象,函数和变量自动成为 window 对象的成员。

  • 全局变量是 window 对象的属性。

  • 全局函数是 window 对象的方法。

    甚至(HTML DOM 的)document 对象也是 window 对象属性:

window.document.getElementById("header");
//等价于
document.getElementById("header");

window有两个常用的属性:

innerWidthinnerHeight属性,可以获取浏览器窗口的内部宽度高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高

(兼容性:IE<=8不支持。)

//获取浏览器窗口的内部宽度和高度。
console.log('window inner size: ' + window.innerWidth + ' x ' + window.innerHeight);

//获取浏览器窗口的整个宽高。
console.log('window outer size: ' + window.outerWidth + 'X' + window.outerHeight);

image-20210813233948314

window有几个常用的方法:

alert:警告框

alert('hello world')  

confirm:确认框

语法window.confirm("sometext");

//如果用户单击“确定”,该框返回 true。如果用户单击“取消”,该框返回 false。
window.confirm("sometext");

image-20210814142107253

prompt:提示框

语法:window.prompt("sometext","defaultText");

//如果您希望用户在进入页面前输入值,通常会使用提示框。
var person = prompt("请输入您的姓名", "比尔盖茨");
if (person != null) {
    alert("你好 " + person + "!今天过的怎么样?");
}

image-20210814141809632

image-20210814141734871


navigator对象表示浏览器的信息.

常用属性:

  • navigator.appName:浏览器名称;
  • navigator.appVersion:浏览器版本;
  • navigator.language:浏览器设置的语言;
  • navigator.platform:运行浏览器的操作系统平台。
  • navigator.userAgent:浏览器设定的User-Agent字符串。
//navigator
console.log('appName:' + navigator.appName);//浏览器名称
console.log('appVersion: ' + navigator.appVersion);//浏览器版本
console.log('userAgent:' +navigator.userAgent);//返回由客户机发送服务器的 user-agent 头部的值。
console.log('appCodeName:' + navigator.appCodeName);//返回浏览器的代码名
console.log('language:'+ navigator.language);  //浏览器语言
console.log('platform:'+ navigator.platform);  //浏览器操作系统

image-20210813235342310 请注意,navigator的信息可以很容易地被用户修改,所以JavaScript读取的值不一定是正确的。


screen对象表示屏幕的信息.

常用属性:

  • screen.width:屏幕宽度,以像素为单位;
  • screen.height:屏幕高度,以像素为单位;
  • screen.colorDepth:返回颜色位数,如8、16、24。
//屏幕大小
console.log('Screen size = ' + screen.width + ' x ' + screen.height);
//屏幕颜色位数
console.log('colorDepth = ' + screen.colorDepth);

image-20210814000248518


location对象表示当前页面的URL信息.

常用属性:

  • location.href 返回当前页面的 href (URL)
  • location.hostname 返回 web 主机的域名
  • location.pathname 返回当前页面的路径或文件名
  • location.protocol 返回使用的 web 协议(http: 或 https:)
  • location.assign 加载新文档

http://www.example.com:8080/path/index.html?a=1&b=2#TOP

location.protocol; // 'http' 协议
location.host; // 'www.example.com' 主机
location.port; // '8080' 端口
location.pathname; // '/path/index.html' 路径名
location.search; // '?a=1&b=2' 搜索
location.hash; // 'TOP' 哈希

​ 要加载一个新页面,可以调用location.assign()。如果要重新加载当前页面,调用location.reload()方法非常方便。

location.assign("http://www.baidu.com");//跳转网页
location.reload();//重新加载网页(刷新)

history对象包含浏览器历史.

​ history三个方法:

  • history.back() - 等同于在浏览器点击后退按钮
  • history.forward() - 等同于在浏览器中点击前进按钮

对于现代Web页面来说,由于大量使用AJAX和页面交互,应该减少调用history的方法


6、DOM操作

常用方法

6.1、获取节点

image-20210814150042147

getElementById()    返回带有指定ID 的元素。
getElementsByTagName()  返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)getElementsByClassName() 返回包含带有指定类名的所有元素的节点列表。
getElementsByName(a) 通过name属性获取一组元素节点对象
appendChild()   把新的子节点添加到指定节点。
removeChild()   删除子节点。
replaceChild()  替换子节点。
insertBefore()  在指定的子节点前面插入新的子节点。(一般是父节点调用)
createElement() 创建元素节点。
createTextNode()创建文本节点。
createAttribute()   创建属性节点。
getAttribute()  返回指定的属性值。
setAttribute()  把指定属性设置或修改为指定的值。
当前节点.paretNode   表示当前节点的父节点
当前节点.previousSibling 表示当前节点的前一个兄弟节点
当前节点.nextSibling 表示当前节点的后一个兄弟节点
父节点.firstchild 可以获取第一个子节点(包括空白文本节点)
父节点.firstElementchild 可以获取第一个子元素(不包括空白文本节点)
父节点.childNodes 表示当前节点的所有子节点

第二种方法是使用querySelector()querySelectorAll(),需要了解selector语法,然后使用条件来获取节点,更加方便:

IE < 8不支持querySelectorquerySelectorAll。IE8仅有限支持。

document.querySelector(#a) 通过CSS选择器来获取一个元素节点对象
document.querySelectorAll(span) 通过CSS选择器来获取一组元素节点对象

语法:

参数: CSS的选择器一样

document.querySelector('#a') //id选择器

document.querySelectorAll('span') //获取document中所有的span标签

6.2、更新DOM

获取标签内容

​ boj.innerHTML

修改标签内容 或者 插入标签及内容就是给innerHTML 赋值,但是会覆盖以前的值,如果这个DOM节点不是空的,那就不能这么做,因为innerHTML会直接替换掉原来的所有子节点。

boj.innerHTML = ‘text’

var p = document.getElementById('p-id');
// 设置文本 xxx --> ABC:
p.innerHTML = 'ABC';
// 设置HTML
p.innerHTML = 'ABC <span style="color:red"> RED </span> XYZ';

<body>
    <p id="p-id">xxx</p>
</body>

image-20210814151025950

​ 有两个办法可以插入新的节点。一个是使用appendChild,把一个子节点添加到父节点的最后一个子节点。例如:

方法一:

var js = document.getElementById('js');
var list = document.getElementById('list');
list.appendChild(js);

<p id="js">JavaScript</p>
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

运行结果:

image-20210814152937704

注意:appendChild()首先会从原先的位置删除,再插入到新的位置,

此方法一般是先创建一个节点,在追加

var p = document.createElement('p');
var list = document.getElementById('list');
p.innerHTML = 'xxxx'
list.appendChild(p);

image-20210814154632694

方法二:

insertBefore(a,b)是参照节点,意思是a节点会插入b节点的前面

  1. 先创建新节点
  2. 然后插入到指定位置
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>

//1.
var p = document.createElement("p");
p.innerHTML = 'xxx';
//2.
var list = document.getElementById("list");
var java = document.getElementById("java");
list.insertBefore(p, java);

image-20210814160605975


修改innerTexttextContent属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签:

var p = document.getElementById('p-id');
alert(p.innerHTML);  //xxx
p.innerText = '<span>Hi</span>';

<body>
    <p id="p-id">xxx</p>
</body>

image-20210814151914412


删除节点一个DOM节点

farther.remove()方法

​ 删除一个DOM节点就比插入要容易得多。要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉.(不能通过自己删)

<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>
    <p id="scheme">Scheme</p>
</div>
//删除节点
var farther = document.getElementById('list');
var self = document.getElementById('java');
farther.removeChild(self);
//等价于
var self = document.getElementById("java");
self.parentNode.removeChild(self);

当我们用如下代码删除子节点时:

var parent = document.getElementById('parent');
parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错

浏览器报错:parent.children[1]不是一个有效的节点。原因就在于,当<p>First</p>节点被删除后,parent.children的节点数量已经从2变为了1,索引[1]已经不存在了。

因此,删除多个节点时,要注意children属性时刻都在变化。

注意: 删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。


7、操作表单

  • 文本框,对应的<input type="text">,用于输入文本;
  • 口令框,对应的<input type="password">,用于输入口令;
  • 单选框,对应的<input type="radio">,用于选择一项;
  • 复选框,对应的<input type="checkbox">,用于选择多项;
  • 下拉框,对应的<select>,用于选择一项;
  • 隐藏文本,对应的<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。

获取值

obj.value

​ 但是,对于单选框和复选框,value属性返回的永远是HTML预设的值,而我们需要获得的实际是用户是否“勾上了”选项,所以应该用checked判断:

obj.checked; // true或者false

设置值

obj.value = ‘’

对于单选框和复选框,设置checkedtruefalse即可。


HTML5控件:

HTML5新增了大量标准控件,常用的包括datedatetimedatetime-localcolor等,它们都使用<input>标签:

​ …

不支持HTML5的浏览器无法识别新的控件,会把它们当做type="text"来显示。支持HTML5的浏览器将获得格式化的字符串。例如,type="date"类型的inputvalue将保证是一个有效的YYYY-MM-DD格式的日期,或者空字符串。

没有name属性的<input>的数据不会被提交。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crazy_August

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值