Java(JavaScript02)
参考视频:12. 函数的定义和参数获取(狂神)
4. 函数及面向对象
4.1 定义函数和调用函数
定义函数:
- 定义方式一
绝对值函数
function abs(x){
if(x>=0){
return x;
}else{
return -x;
}
}
- 一旦执行到return,代表函数结束,返回结果。
- 如果没有执行return,函数执行完也会返回结果,结果就是undefined(NaN)。
- 定义方式二
var abs = function(x){
if(x>=0){
return x;
}else{
return -x;
}
}
- function(x){…},这是一个匿名函数。但是可以把结果赋值给abs,通过abs就可以调用函数。
- 方式一和方式二等价。
调用函数:
abs(10) //10
abs(-10) //10
- 参数问题:JavaScript可以传任意个参数,也可以不传递参数。
- 参数进来是否存在问题?
- 假设不存在参数,如何规避?
var abs = function(x){
//手动抛出异常来判断
if (typeof x !== 'number'){
throw 'Not A Number...';
}
if(x>=0){
return x;
}else{
return -x;
}
}
arguments:
- arguments是一个JS免费赠送的关键字。
- 代表了,传递进来的所有的参数,是一个数组!
var abs = function(x){
console.log("x->"+x);
for (var i = 0;i<arguments.length;i++){
console.log(arguments[i]);
}
if(x>=0){
return x;
}else{
return -x;
}
}
- 问题:arguments包含所有的参数,我们有时候想使用多余的参数来进行附加操作。需要排除已有参数。
rest:
- 以前:
if (arguments.length>2){
for(var i=2; i<arguments.length; i++){
//...
}
}
- ES6引入的新特性,获取除了已经定义的参数之外的所有参数。
function aaa(a,b,...rest){
console.log("a->"+a);
console.log("b->"+b);
console.log(rest);
}
- rest参数只能写在最后面,必须用
...
标识。
4.2 变量的作用域
- 在JavaScript中,var定义的变量实际是有作用域的。
- 假设在函数体中声明,则在函数体外不可以使用。(如果一定要实现,在后面可以研究一下闭包)
function zach(){
var x = 1;
x = x + 1;
}
x = x + 2;//Uncaught ReferenceError: x is not defined
- 如果两个函数使用了相同的变量名,只要在函数内部,就不冲突。
function zach(){
var x = 1;
x = x + 1;
}
function zach2(){
var x = 10;
x = x + 10;
}
- 内部函数可以访问外部函数的成员,反之则不行。
function zach(){
var x = 1;
//内部函数可以访问外部函数的成员,反之则不行。
function zach2(){
var y = x + 1;//2
}
var z = y + 1;//Uncaught ReferenceError: y is not defined
}
- 假设,内部函数变量和外部函数的变量,重名!
function zach(){
var x = 1;
function zach2(){
var x = 'A';
console.log('inner'+x);
}
console.log('outer'+x)
zach2();
}
zach();
- 在JavaScript中,函数查找变量会从自身函数开始,由内向外查找。假设外部存在同名的函数变量,则内部函数将会屏蔽外部函数的变量。
- 提升变量的作用域:
function zach(){
var x = "x"+y;
console.log(x);
var y = 'y';
}
- 结果:xundefined
- 结论:js执行引擎,自动提升了y的声明,只是不会提升变量y的赋值。
function zach2(){
var y;
var x = "x"+y;
console.log(x);
y = 'y';
}
- 这个是在JavaScript建立之初就存在的特性。
- 养成规范:所有的变量定义都放在函数的头部,不要乱放,便于代码维护。
function zach2(){
var x = 1,
y = x+1,
z,a,b;//undefined
//之后随意使用
}
- 全局函数:
//全局变量
x = 1;
function f(){
console.log(x);
}
f();
console.log(x);
- 全局对象window
var x = 'xxx';
alert(x);
alert(window.x);//默认所有的全局变量,都会自动绑定在window对象下。
alert()
这个函数本身也是一个window变量。
var x = 'xxx';
window.alert(x);
var old_alert = window.alert;
//old_alert(x);
window.alert = function (){
};
//发现alert()失效了
window.alert(123);
//恢复
window.alert = old_alert;
window.alert(456);
- JavaScript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找。如果在全局作用域都没有找到,报错
ReferenceError
。
- 规范:
- 由于我们所有的全局变量都会绑定到我们的window上。如果不同的js文件,使用了相同的全局变量,会产生冲突。
- 那么如何减少冲突?
//唯一全局变量
var ZachApp = {};
//定义全局变量
ZachApp.name = 'zach';
ZachApp.add = function (a,b){
return a+b;
}
- 把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题。
- jQuery
- 局部作用域:let
function fun(){
for (var i = 0; i < 100; i++) {
console.log(i);
}
console.log(i + 1);//问题:i出了作用域还可以被使用
}
- ES6,let关键字,解决了局部作用域冲突问题。
function fun(){
for (let i = 0; i < 100; i++) {
console.log(i);
}
console.log(i + 1);//Uncaught ReferenceError: i is not defined
}
- 建议使用
let
去定义局部作用域的变量;
- 常量:const
- 在ES6之前,怎么定义常量:只要用全部大写字母命名的变量就是常量。建议不要修改这类值。
var PI = '3.1415926';
console.log(PI);
PI = '3.14159265358979';//可以改变这个值
console.log(PI);
- 在ES6引入了常量关键字
const
const PI = '3.14';//只读变量
console.log(PI);
PI = '123';//TypeError: Assignment to constant variable.
console.log(PI);
4.3 方法
- 定义方法:
- 方法就是把函数放在对象的里面,而对象只有两个东西:属性和方法。
var zach = {
name: '柴客',
birth: 1998,
//方法
age: function (){
// 今年 - 出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
}
//属性
zach.name
//方法,一定要带()
zach.age()
this.
代表什么?拆开上面的代码看看。
function getAge(){
// 今年 - 出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
var zach = {
name: '柴客',
birth: 1998,
//方法
age: getAge
}
//zach.age() 24
//getAge() NaN window
- this是无法指向的,是默认指向调用它的那个对象。
- apply
- 在js中可以控制this指向!
function getAge(){
// 今年 - 出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
var zach = {
name: '柴客',
birth: 1998,
age: getAge
}
var xiaoming = {
name: '小明',
birth: 2000,
age: getAge
}
//zach.age() 24
//getAge() NaN
getAge.apply(xiaoming,[]);//this.指向了zach,参数为空
5. 内部对象
- 标准对象
typeof 123
"number"
typeof '123'
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof {}
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"
5.1 Date
- 基本使用
var now = new Date();//Tue Apr 26 2022 16:37:37 GMT+0800 (中国标准时间)
now.getFullYear();//年 2022
now.getMonth();//月 3(0~11)
now.getDate();//日 26
now.getDay();//星期几 2
now.getHours();//时 16
now.getMinutes();//分 45
now.getSeconds();//秒 23
now.getTime();// 1650962733968 时间戳,全世界统一,从1970年1月1日0点0时0分0秒0毫秒开始计时
console.log(new Date(1650962733968));//时间戳转为时间
- 转换
now = new Date(1650962733968);
Tue Apr 26 2022 16:45:33 GMT+0800 (中国标准时间)
now.toLocaleString();
'2022/4/26 下午4:45:33'
now.toGMTString();
'Tue, 26 Apr 2022 08:45:33 GMT'
now.toLocaleString //注意:调用是一个方法,不是一个属性。
ƒ toLocaleString() { [native code] }
5.2 JSON
- json是什么
早期,所有数据传输习惯使用XML文件!
- JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在JavaScript中,一切皆为对象。任何js支持的类型都可以用JSON来表示。number、string… …
格式:
- 对象都用{}
- 数组都用[]
- 所有键值对都用key:value
JSON字符串 和 JS对象 的转化
var user = {
name: "zach",
age: 18,
sex: '男'
}
//对象转化为json字符串 {"name":"zach","age":18,"sex":"男"}
var jsonUser = JSON.stringify(user);
//json 字符串转化为对象 参数为json字符串
var obj = JSON.parse('{"name":"zach","age":18,"sex":"男"}');
- 很多人搞不清楚,JSON和JS对象的区别。
var obj = {a:'hello',b:'hellob'};
var json = '{"a":"hello","b":"hellob"}';
5.3 Ajax
- 原生的js写法,xhr异步请求。
- jQuery封装好的方法,$(“#name”).ajax(“”)
- axios 请求
6. 面向对象编程
- 原型对象:
javascript、java、c#… …面向对象;JavaScript有些区别!
- 类:模版 原型对象
- 对象:具体的实例
在JavaScript中,这个需要换一下思维方式!
- 原型:
var Student = {
name: "zach",
age: 18,
sex: '男',
run: function (){
console.log(this.name + "running...");
}
};
var xiaoming = {
name: "小明"
};
//原型对象
xiaoming.__proto__ = Student;
var Bird = {
fly: function (){
console.log(this.name + "flying...");
}
};
//小明的原型是Student
xiaoming.__proto__ = Bird;
- 以下是原生的构造方法,但是建议使用class关键字(ES6引入的)
function Student(name){
this.name = name;
}
// 给student新增一个方法
Student.prototype.hello = function (){
alert('hello~')
};
- class(对象)继承:
class关键字,是在ES6引入的。
- 定义一个类:属性,方法
//ES6之后-----
//定义一个学生的类
class Student{
constructor(name) {
this.name = name;
}
hello(){
alert('hello')
}
}
- 继承
<script>
//ES6之后-----
//定义一个学生的类
class Student{
constructor(name) {
this.name = name;
}
hello(){
alert('hello')
}
}
class XiaoStudent extends Student{
constructor(name,grade) {
super(name);
this.grade = grade;
}
myGrade(){
alert('我是帝丹小学的小学生');
}
}
var xiaoming = new Student("修明");
var xiaohong = new XiaoStudent("修红",1);
</script>
-
本质:查看对象原型
-
原型链:
__proto__
: