JavaScript学习(二)
- 函数
- 内部对象
- 面对对象编程
一、函数
1.1 两种函数的定义方式
//两种方式都可以,习惯哪个用哪个
function hello() {
alert('hello')
}
var test = function() {
alert('heelo2')
}//function(){}这是一个匿名函数,但是可以把结果赋值给test,通过test可以调用函数.
注意
:即使函数没有执行return,也会返回结果,不会报错。执行的结果是 undefined
在浏览器中的调用格式如下
test()
hello()
1.2 函数的参数问题
在JavaScript中,函数的参数可以不传,也可以传多个。都不会报错。但是这样很不严谨。
- 不传参数
function abs(x){
if (x>0){
return x;
} else{
return -x;
}
}
在浏览器中调用时不传递参数,结果如下
abs()
NaN
- 如何规避不传参数的问题?
可以通过手动抛出异常的方式规避
function abs(x){
if (typeof x!=='number'){
throw 'not a numner';
}
if (x>0){
return x;
} else{
return -x;
}
}
浏览器中再次不传参数调用,结果如下
abs()
Error: not a numner
- 传入多个参数的问题
在浏览器中调用上述函数时,传入多个参数,结果如下。
abs(1,2,3,4)
1
- 传递进来的未定义的参数。也是存在的。JavaScript赠送了一个关键字,
arguments
。这个关键字就代表传递进来的所有参数。是个数组。
function abs(x){
console.log(x);
for (let i=0;i<arguments.length;i++) {
console.log (arguments[i]);
}
}
在浏览器中调用后,结果如下。
abs(1,5,3,6)
undefined
1
5
3
6
- 有时候,我们想要一个不包含已经定义过的参数的数组(也就是“多余的参数”的数组),我们可以使用另一个关键字
rest
。这个关键字就代表多余的参数。是ES6引入的新特性。
//使用rest的格式如下必须用...标识rest
function abs(x,...rest){
console.log(rest);
}
在浏览器中调用后,结果如下。不包含已经定义过的x,数组中是其他的未定义的函数
abs(1,2,3,4,5,6)
undefined
Array(5) [ 2, 3, 4, 5, 6 ]
1.3 变量的作用域
在JavaScript中。函var定义的变量是有作用域的。下面代码进行测试。
function test (x){
var x=1;
}
alert(x);//浏览器调用结果为 ReferenceError: x is not defined
-------------------------
function test (x){
var x=1;
alert(x);
}
function test2(x) {
var x = 2;
alert(x);
}//浏览器中,两个函数都可以调用。说明不同的函数中变量同名不冲突。
-------------------------
function test() {
var x = 1;
function test2() {
var y = x + 1;
}
var z = y + 1;
}// y is not defined,内部函数可以访问外部函数的成员外部函数不能访问内部函数的成员
-------------------------
function test() {
var x = 1;
function test2() {
var x = 'A';
console.log('inner'+x);
}
console.log('outer'+x);
}//就近原则
-------------------------
function test() {
var x='x'+y;
console.log(x);
var y='y';
}//xundefined JavaScript会自动提升y的声明。但是不会提升y的赋值。所以最好将变量在最开始就都放在函数的头部。
//下面举例
function test() {
var x = 1,
y = x + 1,
z,i,a;
// 之后随意用
}
-------------------------
总结:
- 定义在函数中,函数外无法使用
- 两个函数有同名的变量。则互不影响
- 内部函数可以访问外部函数的变量。反之不可以
- 内部函数和外部函数拥有同名的变量,则使用就近原则
- JavaScript会自动提升变量的声明到头部。但是不会提升变量的赋值。
- 最好在函数刚开始就直接将所有的变量都声明
1.4 全局变量
var x=1;
function test2(){
console.log(x)
}
test2();//打印成功
console.log(x);//打印成功
- JavaScript中所有的全局变量,会自动绑定在window对象下。也就是说,下面两个是等价的。
var x=1;
alert(x);
alert(window.x)
- **alert()**这个方法本身也是一个window变量。也就是说。上述代码可以 写成下面的,效果不变。
var x=1;
alert(x);
window.alert(window.x)
- 并且,是变量就可以赋值。我们可以给alert()方法赋值。使别的变量具有alert()的方法。或者使alert()方法失效。
var x = 1;
alert(x);---弹窗1
window.alert() = function () {}
alert(window.x)--弹窗失败
- 注意:JavaScript中如果所有的变量都绑定到了window下。那么不同的js文件很可能会导致冲突。解决冲突的方法如下:
//自己定义一个对象,所有的全局变量都绑定在这个对象下。不再绑定到window下。那么就可以避免冲突了
var word={};
word.name='haha';//全局变量
word.age=16;//全局变量
let
关键字,
function aaa() {
for (var i = 0; i < 100; i++) {
console.log(i)
}
console.log(i+1); //打印成功.说明i处了上述作用域还可以使用,这明显是不适合的,所以我们使用关键字 let 将变量定义为局部变量。那么就可以限定他的作用域了
}
function aaa() {
for (let i = 0; i < 100; i++) {
console.log(i)
}
console.log(i + 1); //打印失败.
}
-
常量
ES6以前。并没有专门设置常量的关键字。我们都使用约定俗成的办法。也就是说,我们相互约定,使用大写字母表示常量,大家都不要去修改他们了(实际上他们完全可以被修改)。
ES6之后。引入了关键字
const
可以定义常量了。const num=1; num=3;//Attempt to assign to const or readonly variable 尝试修改失败
1.5 方法
-
方法的定义
其实和函数一样,只不过是把函数放到了对象里。
var student ={
name:'student',
age:12,
hello:function () {//方法
alert('hello')
}
}
- this 关键字
function abs() {
if (this.num > 0) {
return this.num;
} else {
return -this.num;
}
}
var test= {
num:-1,
end:abs
}
//调用abs()方法时结果为 NaN
//调用test.end()时结果为 1
// this代表调用它的那个对象
-
apply
在JavaScript中,可以指定this的指向。
function getAge() { var now = new Date().getFullYear(); return now - this.bitrh; } getAge.apply(xiaoming, [])//指定指向 var xiaohua = { name: 'xiaohua', bitrh: 2000, age: getAge }; var xiaoming = { name: 'xioming', bitrh: 200, age: getAge };
二、内部对象
2.1 标准对象
typeof 123
"number"
typeof '123'
"string"
typeof true
"boolean"
typeof []
"object"
typeof {}
"object"
typeof Math.abs
"function"
typeof NaN
"number"
typeof undefined
"undefined"
2.2 Date
- 基本使用
var now = new Date();
now.getFullYear(); //年
now.getMonth(); // 月
now.getDate(); // 日
now.getDay(); // 星期几
now.getHours(); // 时
now.getMinutes(); // 分
now.getSeconds(); // 秒
now.getTime(); // 从1970 1.1 0:00:00到现在的毫秒数
- 转换
now.toLocaleString()
"2020/2/10 下午10:49:10"
now.toGMTString()
"Mon, 10 Feb 2020 14:49:10 GMT"
2.3 JSON
-
定义
JSON是一种轻量级的数据交换格式,简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言.易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
也就是说:
json是一种数据交换格式
因为简洁和清晰的结构,使的他成为理想的数据交换语言.
JavaScript中所有对象,所有的js支持的类型都可以用记送来表示
-
格式
对象都用大括号
数组都用中括号
所有的键值对 都是用 key:value
-
转换
var user = { name: "xiaohua", age: 7, sex: '男' } //将对象转化成字符串 var jsonUser = JSON.stringify(user); //转换结果"{\"name\":\"xiaohua\",\"age\":7,\"sex\":\"男\"}" //将字符串转换成对象 var obj = JSON.parse("{\"name\":\"xiaohua\",\"age\":7,\"sex\":\"男\"}");
三、面对对象编程
3.1 原型对象 类似于Java中的类
var user = {
name: "xiaohua",
age: 7,
sex: '男'
}
var test={
}
test.__proto__=user;//设定原型对象
alert(test.age)//弹窗7
3.2 给test增加新的方法
var user = {
name: "xiaohua",
age: 7,
sex: '男'
}
var test={
}
test.sing=function(){
alert('sing')
}
test.__proto__=user;
alert(test.age)
3.3 给函数增加新的方法
function Student(name) {
this.name = name;
}
// 给student新增一个方法
Student.prototype.hello = function () {
alert('Hello')
};
3.4 class继承
继承是ES6之后引入的
- 定义一个类
class test{
constructor(name){
this.name=name;
}
hello(){
alert('hello')
}
}
var xiaobai=new test("xiaobai");
xiaobai.hello()//弹窗hello
- 继承
class test {
constructor(name) {
this.name = name;
}
hello() {
alert('hello')
}
}
class test2 extends test {
constructor(name, grade) {
super(name);
}
}
var xiaobai = new test2(xiaobai)
xiaobai.hello()//弹窗成功,说明test2继承了test的hello()方法