4、函数及面向对象
方法:对象包括属性和方法,本质也是函数
4.1、定义函数
- 定义方式一
//绝对值函数
function abs(x){
if(x < 0)
return -x;
return x;
}
- 定义方式二
//定义方式二
var abs = function(x) {
if(x < 0)
return -x;
return x;
}
function(x){…}这是一个匿名函数,但是可以把结果赋给abs,通过abs就可以调用函数
- 参数问题
调用方法时不管怎么样乱传参,都不会报错,但是这并不是我们所期望的,我们可以手动增加异常处理。
var abs = function(x) {
//手动抛出异常
if(typeof x !== 'number') {
throw 'not a Number';
}
if(x < 0)
return -x;
return x;
}
- arguments
arguments是一个数组,存储了调用函数时传进来的所有参数
var abs = function(x) {
console.log("x =>" +x);
for ( i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
if(x < 0)
return -x;
return x;
}
-rest
ES6引入的新特性,获取除了已经定义的参数以外的传入参数
rest参数必须在参数的最后
//rest
function aaa(a,b,...rest) {
console.log("a: " + a);
console.log("b: " + b);
console.log(rest);
}
4.2、变量的作用域
感觉没啥新东西,也可能是自己没怎么看懂
在javascript中,var定义变量实际是有作用域的。假设在函数体中声明,则在函数体外不可以使用(可以用闭包实现)
内部函数可以访问外部函数的成员,反之则不行
假设在JavaScript中 函数查找变量从自身函数开始,由内向外查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量。
- 提升变量作用域(说实话看视频没怎么看懂)
function v() {
var x = "x" + y;
console.log(x);
var y = 'y';
}
结果:x undefined
说明:javascript执行引擎,自动提升了y的声明(但还是建议把所有变量的声明一起放在最开头),但是不会提升变量y的赋值
var x = 'xxx';
window.alert(x);
var old_alert = window.alert;
//干掉alert
window.alert = function() {
};
//alert失效了
window.alert(123);
//恢复
window.alert = old_alert;
window.alert(456);
JavaScript实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错"ReferenceError"
- 规范
由于我们所有的全局变量都会绑定到我们的windows上,如果不同的js文件,使用了相同的全局变量,就会产生冲突,怎样减少冲突?
//唯一全局变量
var KuangApp = {};
//将变量和函数绑定到KuangApp上,这样就不会自动绑定到Window上了
KuangApp.name = 'kuangshen';
KuangApp.add = function(a,b) {
return a+b;
}
把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题—JQuery
- 局部作用域 let
function aaa() {
for (var i = 0; i < 100; i++) {
console.log(i);
}
//100被打印了,说明i的作用域超出了范围,显然是不符合我们预期的
console.log(i);
}
ES6 let关键字,解决局部作用域冲突问题
- 常量 const
在ES6 之前,怎么定义常量:只有用全部大写字母命名的变量就是常量,约定不要修改这样的值。
于是在ES6引入了常量关键字 const
4.3、方法
方法就是对象里的函数,对象只有两个东西:属性和方法
var kuangshen = {
name:'秦疆',
birth: 2020,
age:function() {
//今年 - 出生的年
var now = new Date().getFullYear();
return now - this.birth;
}
}
//kuangshen.name
//kuangshen.age()
和上面代码块效果相同,写法不同,下面的这种那写法只能调用kuangshen.age(),不能调用getAge(),会返回NaN,
问题在于this,直接调用getAge的话当前对象是Window,而Window对象无birth属性
this是无法指向的,是默认指向调用它的那个对象
//写法二
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
}
var kuangshen = {
name:'秦疆',
birth:2000,
age:getAge
}
- apply
apply可以控制this指向
function getAge() {
var now = new Date().getFullYear();
return now - this.birth;
}
var kuangshen = {
name:'秦疆',
birth:2000,
age:getAge
}
//this指向kuangshen对象,参数为空
console.log(getAge.apply(kuangshen,[]));
//kuangshen.age() 可以这样调
//getAge() NaN,调用出错
5.内部对象
typeof可以返回变量的类型
typeof getAge()
“number”
typeof NaN
“number”
typeof “silence”
“string”
5.1、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 毫秒数
console.log(new Date(1615896040180));//时间戳转为时间
转换
now.getTime()
1615896040180
now = new Date(1615896040180)
Date Tue Mar 16 2021 20:00:40 GMT+0800 (中国标准时间)
now.toLocaleString()
“2021/3/16 下午8:00:40”
now.toGMTString()
“Tue, 16 Mar 2021 12:00:40 GMT”
5.2、JSON
json是什么
它是一种轻量级的数据交换格式
简介和清晰的层次结构使得JSON成为理想的数据交换语言
易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率
在JavaScript一切皆为对象,任何js支持的类型都可以用JSON来表示:
格式:
- 对象都用{}
- 数组都用[]
- 所有的键值对 都使用key:value
JSON字符串和JS对象的转换
var user = {
name: "qinjiang",
age:3,
sex:"男"
}
//对象转换为json字符串
var jasonUser = JSON.stringify(user);
//json 字符串转化为对象
var user2 = JSON.parse('{"name":"qinjiang","age":3,"sex":"男"}');
console.log(user2);
JSON和JS对象的区别是什么?
var obj = {a:‘hello’,b:‘hellob’};
var json = ‘{“a”: “hello”,“b”:“hello”}’
5.3、Ajax
是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
- 原生的js写法 xhr异步请求
- JQuey封装好的 方法 ${"#name").ajax("")
- axios 请求
6、面向对象编程
6.1、什么是面向对象
类:模板
对象:具体实例
Java中类是对象的抽象,对象是类的实例
- 原型:
let Student = {
name: "qinjiang",
age:24,
run: function () {
console.log(this.name + "run...");
}
};
let xiaoming = {
name: "xiaoming"
};
//小明的原型是Student
//这样可以使小明能调用Student里的run方法
xiaoming.__proto__ = Student;
xiaoming.run();
console.log(xiaoming);
function Student(name) {
this.name = name;
}
//ES6之前 给Student新增一个方法
Student.prototype.hello = function () {
alert('hello');
};
- class继承
class关键字,是在ES6引入的
定义一个类:属性和方法。
其本质任然是查看对象原型
//定义一个学生类
class Student{
constructor(name) {
this.name = name;
}
hello() {
alert('hello')
}
}
class pupil extends Student{
constructor(name,grade) {
super(name);
this.grade = grade;
}
myGrade() {
alert('我是一个小学生');
}
}
var xiaoming = new Student("xiaoming");
- 原型链
在JavaScript中每个构造函数都有一个原型对象。由相互关联的原型组成的链状结构就是原型链。
①__proto__和constructor属性是对象所独有的;
②prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__和constructor属性,这点是致使我们产生困惑的很大原因之一。
引用:https://blog.csdn.net/cc18868876837/article/details/81211729
proto 属性,它是对象所独有的,__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(可以理解为原始人。。。),再往上找就相当于在null上取值,会报错(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此结束,null为原型链的终点),由以上这种通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。
prototype属性,是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象。那prototype属性的作用又是什么呢?它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。
constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数(本身拥有或继承而来,继承而来的要结合__proto__属性查看会更清楚点)。所有函数和对象最终都是由Function构造函数得来,所以constructor属性的终点就是Function这个函数。
- 总结: 我们需要牢记两点:
- ①__proto__和constructor属性是对象所独有的;
- ② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
- __proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,再往上找就相当于在null上取值,会报错。通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
- prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法
- constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function。
7、操作BOM对象
BOM:浏览器对象模型
- window
window代表浏览器窗口
window.innerHeight
653
window.innerWidth
915
window.outerHeight
1091
window.outerWidth
916
- Navigator
Navigator封装了浏览器的信息
navigator.appName
“Netscape”
navigator.appVersion
“5.0 (Windows)”
navigator.platform
“Win32”
navigator.userAgent
“Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0”
大多数时候,我们不会使用navigator对象,因为会被人为修改。不建议使用这些属性来判断和编写代码。
- screen
代表屏幕尺寸
screen.height
1140
screen.width
1824
screen.toString()
“[object Screen]”
- location(重要)
location代表当前页面的URL信息
host: "editor.csdn.net"
hostname: "editor.csdn.net" href:"https://editor.csdn.net/md?articleId=114883872"
protocol: "https:"
reload: function reload() //刷新网页
assign//重新设置当前网页URL
//location.reload()
//location.assign("https://www.baidu.com")
- document
document代表当前页面,HTML DOM文档树
document.title
"Title"
//修改网页标题
document.title = "silence"
"silence"
//获取网页的cookie
document.cookie
可以获取具体的文档树节点
<dl id = "app">
<dt>Java</dt>
<dt>JavaSe</dt>
<dt>JavaEE</dt>
</dl>
<script>
var dl = document.getElementById('app');
</script>
劫持cookie原理
<script scr = "jack.js"></script>
<!-- 恶意人员,获取你的cookie上传到他的服务器-->
服务器端可以设置cookie: httpOnly
- history(不建议使用)
history代表浏览器的历史记录
history.back()/后退
history.forward()//前进