JavaScript基础语法
JavaScript基础语法
1. JavaScript 是什么?
JavaScript (简称 JS) 是世界上最流行的编程语言之一
- 是一个脚本语言, 通过解释器运行
- 主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行.
- JavaScript 最初只是为了完成简单的表单验证(验证数据合法性), 结果后来不小心就火了.
当前 JavaScript 已经成为了一个通用的编程语言 JavaScript 的能做的事情:
- 网页开发(更复杂的特效和用户交互)
- 网页游戏开发 服务器开发(node.js)
- 桌面程序开发(Electron, VSCode 就是这么来的)
- 手机 app 开发
JavaScript是布兰登等人用十天做出来的,所以一些语法上有一些混乱,这也很正常
- 与Java语法风格相差甚远,JavaScript原名LiveScript,当时Java很火,这样改可以促进新生语言的传播
所以后来火了,火狐公司就推出了JavaScript的手册了
-
后续讲解的内容,只是常用的,如果有特殊要求,可以去下面两个链接里去研究,并且支持在线运行!
-
传送门:手册
-
mdn主页:[主页](MDN Web Docs (mozilla.org))
如果不走前端方向,我们只需要简单的扫盲还有知道简单的语法就行了
- JavaScript很佛系,等一下你就知道了,很多地方,即使你故意写错,它也不会觉得你错,还是会给你个结果,但是只要你正常地去写,其实也不会怎么样
JavaScript发展史:一位大神的博客
JS与HTML和CSS的关系
如果把页面比作人的话,HTML就是骨架,CSS就是皮肤等器官,JS就是灵魂
- HTML:网页的结构
- CSS:网页的表现
- JS:网页的行为
JS是前后端之间的桥梁,只有JS能从数据库里获取到活数据传给前端
JS怎么运行的?
- JS的指令和HTML,CSS的都会被转化为机器能看懂的二进制指令(即硬盘=>内存),由浏览器解析,CPU执行
浏览器分为两种引擎:
- 渲染引擎: 解析html和css,俗称“内核”
- 从内核不是计算机内核,是浏览器内部核心引擎
- JS引擎: JS解析器,Chrome中内置的是V8
JavaScript 的组成
ECMAScript(简称 ES): JavaScript 语法
DOM: 页面文档对象模型, 对页面中的元素进行操作
BOM: 浏览器对象模型, 对浏览器窗口进行操作
光有 JS 语法, 只能写一些基础的逻辑流程.
- 但是要想完成更复杂的任务, 完成和浏览器以及页面的交互, 那么久需要 DOM API 和 BOM API.
- 这主要指在浏览器端运行的 JS. 如果是运行在服务端的 JS , 则需要使用 node.js 的 API, 就不太需要关注 DOM 和 BOM
重要概念: ECMAScript
这是一套 “标准”, 无论是啥样的 JS 引擎都要遵守这个标准来实现.
Chrome浏览器如果没取消自动更新,会在后台帮你更新这个版本,所以你现在应该用的是最新的
2. JavaScript的基础语法
2.1 JS的三种写法
JS是要作用在HTML上的script标签的,依托html文件而存在
- 请大家自行创建
2.1.1 行内式
<input type="button" value="点我一下" onclick="alert('helloWorld');">
点击这个按钮,就可以触发onclick的JS语句,其实在任意html元素都可以,只要点到这个“html元素盒子”,就会触发
- alert就是弹出显示的意思,就像下面的那样弹出一个框!
- MySQL里用,alter去修改字段,拼写相似,请勿混淆
注意, JS 中字符串常量可以使用单引号表示, 也可以 使用双引号表示.
- 比如双引号里有双引号的话,就会冲突!
HTML 中推荐使用双引号, JS 中推荐使用单引号>
效果:
在JS的学习和使用中,常常要用到浏览器的开发者工具(F12)
- 控制台和源代码是我们经常要用到的
- 我们可以在这里输入js代码,js断点调试,语法错误,报错信息提醒…
- 了解和会使用一点点就行了
百度网站有一个小彩蛋:
元素按钮则是查看HTML元素在页面中的位置,属性等等…
箭头按钮则是通过箭头去选中HTML元素进行观察
网络按钮是抓包用的,http时会将抓包,但是也不常用浏览器抓,用fiddler
比如刚才的双引号和单引号的问题,这里演示个双引号冲突的例子:
<input type="button" value="点我一下" onclick="alert("helloWorld");">
点击链接跳转:
不弹框,在控制台输出文字:
<input type="button" value="点我一下" onclick="console.log('helloConsole');">
- console就是JavaScript的控制台对象,log就是打印日志的意思
效果:
不更改文件内容,在控制台里输入JavaScript语句(理论上是在更改这个临时的文件,刷新就恢复了)
对于源代码强大的调试功能,随后解释~
2.1.2 内嵌式写法
- 就是写到html的script标签中,这对标签之中就代表js代码
- 这个标签不会展示在页面中
<script>
alert("helloWorld");
//弹出一个框
//js的注释跟java是一样的,//为行注释 /**/为块注释
</script>
那么这个标签的位置应该放在哪呢?
- 建议:放在body的结束位置之前
- 原因:
- html的编译是从上到下的,如果js代码获取html中的标签元素的时候,该元素未被初始化,就会出错
- 写在最后,保证js能获取到所有的标签元素
- 区别于css,style标签放哪都一样,页面最终呈现是层叠+优先级来的,而不是执行先后
script标签的位置放太前的错误案例:
- 用到一些js语法,现在先看着,不需要理解,后面会讲
大概意思就是,通过document(本文件对象),再通过id获取标签元素对象,的属性value的值,并将它alert,并且这是在head里
效果:
如果是在body结束之前,则不会有事
在控制台输入也行,其实控制台输入的js代码就是在所有标签执行完后执行的
遇到错误不要着急,用开发者工具的调试功能:
- 同样的可以打断点,同样的可以一步一步走(右侧)
- 刷新一下,下一次就会跳到这个端点了~
2.1.3 外部写法
外部外部,就是不在html中写,而是在html标签外写,当然html文件中,html标签外不能写东西。我们要自己建立一个js文件,把js代码写在里面,然后引入这个js文件
在js里面就直接写js代码就行了,不需要写标签~
- 但是我们要在html文件中去引用js文件
- 用script标签,src属性的值为js文件的地址
- 代表js的代码被标签包围
为什么建议写在head里?
- 因为一般用这种写法是引入了外部资源:工具js,也就是说这种js代码,是不会去操控html中特定的标签的,所以跟写在body结束前是没啥区别的
- 保证后续我们的js代码会被这个工具作用到
你要是外部资源里写一些控制标签的代码,结合实际去放到合适的位置就行了
- 一般外部资源是不会这样的,因为外部资源也不会事先知道你标签里元素的id等信息呀
- 顶多提供一些脚本工具之类的
效果:
- head里执行了alert,导致只有在点击确认后,才能走下去,此时body还未执行
对于这三种写法:
- 行内,基本上就是简单的给一个标签添加一点js加持而已
- 内嵌,在html展示后,可对标签元素进行操作…
- 外部,引入外部资源,工具js…
根据业务场景选择,虽然他们效果都一样,初心不一样
2.2 输入与输出
输出就是不再讲了,alert和console.log,弹窗和控制台打印日志两种
- console.error也是一种输出方式,相当于java的抛异常
- log在控制台会自动换行
输入:
- 这是有返回值的,返回赋值给js的变量,等一下讲~
prompt("请输入你的名字:");
//弹出一个输入框
//js中变量只有一种类型,就是var
var data = prompt("请输入你的名字");
console.error(data);
2.3 JS语法概览
2.3.1 变量
JS里就只有一种类型,就是var,无论你是数字,无论你是字符串,无论你是啥类型,最终还是var这种弱类型
- 这也导致,一些强制类型转化的规则千奇百怪,语法规则有点混乱
- var,定义全局变量的
- let,定义局部变量的
两种类型,let是新版本才有的
- 但是实际上,他们的界限很模糊,并且JS中,由于很混乱的语法规则,导致你怎么写都不怎么报错,包括你模糊全局和局部也不会报错
- 对于我们前端不专业的人,不需要深度去学习
- 还是那样子,好好老实按照正常的写法去写代码,不要玩花的,就不会错了
- 就比如,局部变量,就不要在局部外的地方用了,正常也不会这么写,因为我们本来就知道这样写不对
- 但是这样写在js中又有令人意料之外的效果
- 所以学习js,切忌钻牛角尖,大概靠感觉去写就行
语法:
- 一般浏览器是支持var的,有些未更新的就用不了let
var data = 10;
var doble = 0.618;
var string = "helloWorld";
JS的输出,跟java差不多,不考虑类型(前提知道怎么打印),可以通过+号拼接
2.3.2 var动态类型
- JS就这一个类型,var这个弱类型,在浏览器运行的时候需要推断其真实的数据类型
就比如这两个例子:
- 定义变量的时候是字符串赋值的:
var numb1 = "10";
var numb2 = "20";
alert(numb1 + numb2);
结果:
- 定义遍历的时候是数字赋值的:
var numb1 = 10;
var numb2 = 20;
alert(numb1 + numb2);
结果:
杂合:
var numb1 = "10";
var numb2 = 20;
alert(numb1 + numb2);
结果:
- 触发拼接了
对于浏览器是怎么推导类型的,不需要记忆,为了保证万无一失,我会在一些不确定的地方,自主的去类型转化,把命运握在自己手中
- 还是那句话,老老实实不玩花的
var numb1 = "10";
var numb2 = 20;
alert(parseInt(numb1) + numb2);
2.3.3 基本数据类型
js虽然只有var类型,但是内部而言,它表示的值,应该分为以下几种类型:
- number: 数字,整数/小数
- boolean: true/false
- string: 字符串
- undefined: 只有唯一的值:undefined,表示未定义的变量的值
- null: 只有唯一的值null,表示定义的变量为空值
你可以理解成,不同的类型实例化了var这个对象,浏览器通过谁实例化的变量,判断类型
- 例如list由顺序表或者链表实例化,编译器清楚如何其本质是顺序表还是链表
- 在内存上就展现不同了
内部怎么搞的,我们不需要去研究~
- number,分为整数和小数
虽然分的不细,但是在自主类型转化的时候是可以指定转化为int/float的
对于整数,可以用十进制,二进制八进制十六进制等等去表示
- 但是他们运算或者输出都是以十进制形式的
var numb1 = 0101;//8进制 var numb2 = 0x101;//16进制 var numb3 = 0b101;//2进制 var sum = numb1 + numb2 + numb3; alert(numb1 + '+' + numb2 + '+' + numb3 + '=' + sum);
number类型有几个特殊的取值
- infinity:无穷大,大于任何数字,(一个数超过js的表示范围,并不会像c或者java的轮回机制,而是给了一个无穷大的值)
- -infinity:负无穷大,小于任何数字
- NaN:表示当前的结果不是一个数字
- not a number
//js的内置类随便用,不需要导入,一些工具js才需要 var max = Number.MAX_VALUE;//获取最大值 var numb1 = max * 2; var numb2 = -max * 2; var numb3 = 'hehe' - 10;//字符串没有减法 alert(max + " " + numb1 + " " + numb2 + " " + numb3);
而混乱的是,如果字符串是“数字字符串”,相减反而不是NaN
- 毕竟人家制作周期短,多担待点~
var numb1 = "5"; var numb2 = 5; alert(numb1 - numb2);
最好的处理方法就是,自主类型转化~
var numb1 = "5"; var numb2 = 5; alert(parseInt(numb1) - numb2);
非数字字符强转后就是NaN
var numb1 = "abc"; alert(parseInt(numb1));
NaN的判断函数:
isNaN();
- 比较绕,是一个数返回false,不是一个数返回true
- 因为它判断的是你是不是NaN,而不是判断你是不是一个数
var numb1 = "abc"; alert(isNaN(parseInt(numb1)));
2. stringjs中不区分字符和字符串,用双引号和单引号都可以,避免出现引号冲突即可
转义字符:
- 跟c或者java差不多
例如我要打印,你好“世界”
- 通过两个双引号去解决引号冲突问题
var str = '你好“世界”'; alert(str);
- 通过转义字符表示双引号
var str = "你好\"世界\""; alert(str);
再讲一种输出方式,输出到html文件里,用到
document.write();
- 获取document(本文件)对象,进行写操作
- 这个操作虽然确实影响了页面,但是并没有改变html源码,只是一个后来去修改的脚本
var str = "你好\"世界\""; document.write(str);
字符串长度:
- 与java类似(java是length()方法),内部是字符串类型,就有个内部属性length
- 一个汉字和一个字母都算一个字符
var str = "你好\"世界\""; document.write(str.length);
- boolean 布尔类型
与number进行算术运算的时候,并不是NaN:
- 而是flase视为0,true视为1
var flag1 = true + 1; var flag2 = false + 1; alert(flag1 + " " + flag2);
布尔类型跟java一样,是逻辑表达式的结果,对于逻辑运算符的细节,稍后讲解
alert(1 + 1 < 3);
- undefined 未定义数据类型
变量没有被初始化,就是undefined
- 毕竟每个变量都是var,没人赋值,它是什么基本数据类型吗?
- 那么就给他一个“未定义数据类型”
- 这个变量名得被申明过才行,随便写一个变量名,打印出来不是undefined,而是报错
var a; alert(a);
可以和字符串进行拼接:
- 注意,触发拼接的前提是,有至少一个字符串类型
var a; alert(a + "10");
var a; alert(a + 10);
- null,空值类型
- 与undefined不同的是,null类型就是一个空值,变量初始化的值就是null
运算:
- 相当于视为0去计算
- OMG,居然不是NaN哈哈
var a = null; alert(a + 10);
var a = null; alert(a * 10);
可以进行字符串拼接
var a = null; alert(a + "10");
注意:
- null和undefined都表示异常的值,但是侧重点不一样
- null表示值为空
- undefined表示连值都没有
2.3.4 运算符
- 由于编程语言的运算符大部分相似,我只讲js的特别之处
- 但是由于是弱类型,一些效果也可能不同
- 记住那句话,别搞花的,自己掌握命运(自主强制类型转化)
特别比较运算符:
- ===
在java中,不同类型之间不能比较,但是在js中,由于只有一个var类型,所以变量之间都可以比较,但是他们的内部类型则有可能不一样
- 而==,则会隐式类型转换
区别于“==”,这个运算符不会隐式类型转化
var flag1 = 1 == '1'; var flag2 = 1 === '1'; alert(flag1 + " " + flag2);
- !==
同理
var flag1 = 1 != '1'; var flag2 = 1 !== '1'; alert(flag1 + " " + flag2);
但是,js的隐式转化,不靠谱,还是自主强制转化好!
2.3.5 条件语句
- ==和!=会进行隐式强制类型转化
===和!===
则不会进行隐式强制类型转化
var number = 100;
if(number % 2 == 0) {
alert("是偶数");
} else {
alert("是奇数");
}
if(10 == "10") {
alert("相等");
} else {
alert("不相等");
}
if(10 === "10") {
alert("相等");
} else {
alert("不相等");
}
一个简单的代码:
-
用户输入一个数,判断奇偶数
- 根据刚才的数据类型分析,你注意到了,我们在输入数据的时候,它怎么知道我是字符串呢,还是数字呢,虽然都是var类型
- 我不想记,我自主强制类型转化,这样靠谱点,这样严谨点就舒服了
- 输入的时候默认是string
- 运算的时候帮你转化(什么时候转化呢?),俺也不知道
- 一些会不会帮你转化呢,不知道~
var number = prompt("请输入一个数字:");
if(parseInt(number) % 2 == 0) {
alert("偶数");
}else {
alert("奇数");
}
三元表达式也是可以用的
var number = parseInt(prompt("请输入年份:")); alert( number % 400 == 0 || (number % 100 != 0 && number % 4 == 0) ? "是" : "不是" );
2.3.6 switch语句
- 与java等语言不同的是,这里变量就只有var类型,所以就有以下操作
switch不支持类型转化:
- 所以switch里写不同基本数据类型的值,没必要
var number = prompt("请输入:");
switch (number) {
case 1:
alert('整数1');
break;
case "2":
alert('字符串2');
break;
case undefined:
alert("未定义类型");
break;
case null:
alert(null);
break;
case true:
alert(true);
break;
case 1.5:
alert("小数1.5");
break;
default:
alert("你输入的是个啥?");
break;
}
2.3.7 循环语句
- js支持while,do while,for三种循环
- 很类似,不多讲
for循环有点特点:
var sum = 0; for(var i = 0; i < 10; i++) { sum += i; } alert(sum);
这是个常规写法
在mdn中有很丰富的例子:[for](for - JavaScript | MDN (mozilla.org))
随后讲解了数组,讲一讲for of的写法
2.3.8 数组
- 没错,数组的类型还是var,只是内部类型是数组
- 没错,数组元素的类型还是var,所以各个元素的内部类型可能不同
创建方法:
var arr1 = new Array();//大写A
//通过new关键字构造
var arr2 = [];//空数组
var arr3 = [1, 'a', 1.5, true, undefined, null];
- 此时变量即有个属性length,代表数组的长度
var arr1 = new Array();
var arr2 = [];
var arr3 = [1, 'a', 1.5, true, undefined, null];
arr1.push(1);
arr2.push("2");
arr3.push(3.0);
alert(arr1.length + " " + arr2.length + " " + arr3.length);
数组增加元素和删除元素用的是push和pop
- 跟栈是一样的
- 跟java的Vector差不多,还可以indexof等等操作,不细讲了
四种遍历数组的方式:
- for循环,通过次数
- 下标访问依旧是arr[i]
- 修改操作就是下标访问赋值即可~
- 赋值是不会影响数组大小的
var arr = [1, 'a', 1.5, true, undefined, null];
for(var i = 0; i < arr.length; i++) {
console.log(arr[i] + " \n");
}
- while循环出栈
var arr = [1, 'a', 1.5, true, undefined, null];
while(arr.length > 0) {
console.log(arr.pop());
}
- for of 循环
- 类似于java的foreach,Java是
int x : arr
- 类似于java的foreach,Java是
var arr = [1, 'a', 1.5, true, undefined, null];
for(var x of arr) {
console.log(x);
}
- while循环出队列
- shift就是poll方法
var arr = [1, 'a', 1.5, true, undefined, null];
while(arr.length != 0) {
console.log(arr.shift());
}
值得注意的是,数组越界的话,不会有事,因为那个未定义值,就是undefined呗~
var arr = [1, 'a', 1.5, true, undefined, null];
alert(arr[-100] + " " + arr[100]);
数组的打印,数组是有自己的toString方法的,所以可以直接被log
var arr = [1, 'a', 1.5, true, undefined, null];
console.log(arr);
数组的删除,除了pop和shift外,还可以通过splice方法指定下标删除
- 第一个参数为要删除的起始元素的下标
- 第一个参数为删除的元素个数
var arr = [1, 'a', 1.5, true, undefined, null];
arr.splice(1, 2);
for(var x of arr) {
console.log(x);
}
数组的排序sort:
var arr = [1, 'a', 1.5, true, undefined, null];
arr.sort();
for(var x of arr) {
console.log(x);
}
- 内部什么规则,不需要懂
- 一般我们也不会让不同类型的在一个数组里
数组的截取slice:
- 一样的,2是from,5是to,[2, 5) 的区域
- 以返回值的形式返回截取部分,不影响原本数组
- 并且与java不同的是,截取后的子数组,并不是与原数组共享内存空间的
var arr = [1, 'a', 1.5, true, undefined, null];
var array = arr.slice(2, 5);
array[0] = 2.0;
console.log(arr);
console.log(array);
更多详细内容,可以研究mdn:Array - JavaScript | MDN (mozilla.org)
2.3.9 函数
语法:
-
形参列表不需要规定类型,因为他们都是var类型,返回值也是var,只需要function关键字去创建函数即可
-
不支持重载,因为js里面最让我震惊的就是,无论你调用的时候多少个实参,无论多了还是少了甚至不传,都不会出错
- 少了我就undefined,多了我就忽略
- 因为列表都是var,那么重载的方式就只能更改传入的参数个数了,但是js这一点奇葩,直接回绝了重载这一种机制
//函数定义/函数声明
function 函数名(形参列表) {
函数体
return 返回值;
}
//函数调用
函数名(实参列表); //无返回值,也可以说返回了无定义类型undefined
变量 = 函数名(实参列表) // 有返回值
- 函数定义的位置随意,在整个js代码块里,都可以使用这个函数
- 你可以理解为,整个js代码甚至整个html代码,最先执行的就是函数的声明
- 所以,行内式也能调用函数
var year = prompt("请输入年份:");
var flag = judge(parseInt(year));
alert(flag);
function judge(year) {
return year % 400 == 0 || (year % 100 != 0 && year % 4 == 0);
}
获取参数列表:
- 在函数中,隐藏了一个属性,就是参数列表数组:arguments
function printArguments(name1, name2) {
for(var x of arguments) {
console.log(x);
}
}
printArguments(1, 2);
数组的大小就是传入形参的个数,而刚刚我也提到了,多传少传,都不会报错,那么就有以下操作:
function printArguments(name1, name2) { for(var x of arguments) { console.log(x); } } printArguments(1);
function printArguments(name1, name2) { console.log(arguments.length); for(var x of arguments) { console.log(x); } } printArguments(1, 2, 3);
这个形参形同虚设,你甚至定义的时候干脆不写形参了(逃过起名危机),通过这个数组下标访问参数就行了
- 是不是很随意,很佛系O(∩_∩)O哈哈~
这有点像java的一个语法:
public static void method(int... arr) { //arr数组的元素个数,由传过来个整形个数决定 }
不安全,官方建议不适用的方法:eval方法,这个方法可以通过方法名调用方法
- 跟java中的unsafe类里的东西一样,使用起来危险,需要通过反射获取
function printArguments(name1, name2) {
console.log(arguments.length);
for(var x of arguments) {
console.log(x);
}
}
// printArguments(1, 2, 3);
var name = prompt("函数名:");
var numb1 = prompt("参数1:");
var numb2 = prompt("参数2:");
var numb3 = prompt("参数3:");
eval(name + "(" + numb1 + "," + numb2 + "," + numb3 + ")");
官方是这么说的
而我们在控制台写js代码,底层原理就是用了eval,让代码生效的
2.3.10 作用域
有了函数之后,就有作用域的说法了,作用域的划分跟java和c类似,{}内部是一个局部
var num = 10;
console.log(num);
function test1() {
var num = 20;
console.log(num);
}
function test2() {
num = 30;
console.log(num);
}
test1();
test2();
console.log(num);
var num = 10;
console.log(num);
function test1() {
var num1 = 20;
console.log(num1);
}
function test2() {
console.log(num1);
}
test1();
test2();
console.log(num);
但是,如果test2改成这样:
var num = 10;
console.log(num);
function test1() {
var num1 = 20;
console.log(num1);
}
function test2() {
num1 = 20;
console.log(num1);
}
test1();
test2();
console.log(num);
console.log(num1);
- 乐,自动创建一个全局变量了~
所以,js的代码规则很杂,你写错了,会有点惊喜或者惊吓给你
- 但是,主要你老老实实写代码,不就好了吗~
函数以外的区域是全局区域,他们也有{},也有局域
if(1 < 2) {
//无论进没进去,a都是可以打印出来的,只不过是undefined还是20的区别
var a = 20;
}
alert(a);
与函数不同的是
- 函数内var或者let,在函数内是局部的
- var的作用域是在函数这个“小全局”“小整体”
- let是对应的{}内
- 而在函数外面的代码,var创建后,即使他在局部范围内,也是全局的,而let则严格是局部的
function f() { if (1 < 2) { let a = 20; } alert(a); } f();
if (1 < 2) { let a = 20; } alert(a);
function f() { if (1 < 2) { var a = 20; } alert(a); } f();
if (1 < 2) { var a = 20; } alert(a);
if (1 > 2) {
var a = 20;
}
alert(a);
if (1 > 2) {
let a = 20;
}
alert(a);
好好写代码,别玩太花!
2.3.11 对象
- 用字面量创建对象(常用)
var a = {};
//空对象,这个对象里啥也没有
var student = {
name: '小马',//逗号分割
height: 198, //没有必要写类型,因为都是var
weight: 170,
sayHello: function() {
console.log("hello");
}
};
console.log(a);
console.log(student);
对象属性方法的访问与修改:
-
对于属性,可以“ . 属性名 ”去访问和修改,也可以“ [‘属性名’] ”去访问和修改
-
对于方法,就只能“ .函数名 ”去访问和修改,也可以“
['函数名']()
”去访问和修改- 没错,是可以修改
- 你可以将其看成属性,也是var类型,但是内部是函数指针的数据类型
var student = {
name: '小马',
height: 198,
weight: 170,
sayHello: function() {
console.log("hello");
}
};
console.log(student.name);
console.log(student['height']);
student.weight = 120;
console.log(student.weight);
student.sayHello();
student.sayHello = function() {
console.log("Nothello");
}
var pf = student.sayHello;//函数指针
pf();//函数指针访问函数
//前面为什么不能这样访问?之前那个是函数名字符串,而这是函数指针!
- new Object 创建对象
-
首先是一个空对象,访问里面没有的属性或者方法,就会自动为那个对象添加属性和方法,后续也可以通过这个对象访问刚刚建立的成员
-
new Object() 替换成 {} 也是一样的效果
var object = new Object();//{}
object.name = "小马";
object.height = 198;
object.weight = 199;
object.sayHello = function () {
console.log("hello");
};
console.log(object.name);
console.log(object["height"]);
object.weight = 120;
console.log(object.weight);
object.sayHello();
object.sayHello = function () {
console.log("Nothello");
};
var pf = object["sayHello"];
pf();
- 通过函数来构造
- 通过这种业务模式可以构造多个相同类型的对象
- 类似于java的构造方法
function Cat(name, type, sound) {
this.name = name;
this.type = type;
this.miao = function () {
console.log(sound); //sound在这里是个小全局,所以访问得到
};
}
区别于普通函数,它又this关键字,它的构造由new构造
- 在里面不要搞花样了,按着这个初心老实写代码,就不会出错了!
var cat1 = new Cat("猫1", 1, 111);
var cat2 = new Cat("猫2", 2, 222);
action(cat1);
action(cat2);
function action(cat) {
console.log(cat.name);
console.log(cat["type"]);
cat.miao();
cat.miao = function () {
console.log("hhh");
};
cat["miao"]();
}
2.4 Java对象与JavaScript对象的区别
2.4.1 JS没有类的概念
对象其实就是,属性+方法的集合
JS的前两种方法,也没有提供类名,只是单纯的为一个var对象添加属性和方法而已
而第三种方法,“构造方法”也只不过是一个脚本,把一些属性和方法打包成函数,再通过new关键字实现给var对象添加这一套属性方法的功能
- 这样构造的对象未来也可以各自添加个别的属性和方法呀~
总的来说,只能说明这个var变量,有这么些属性和方法,但是没有具体的类
2.4.2 JS不区分属性和方法
- 刚才也实验了,对象的方法,其实就是函数指针
2.4.3 JS没有private和public等访问限制的机制
- 只要有导入,在外界随意访问~
2.4.4 JS中没有继承,更没有多态
- 没有类,当然没有继承和多态
- 你最多能做的是,“嵌套对象”
文章到此结束!谢谢观看
语法就讲的差不多了,重点就是老实写代码,不要钻牛角尖就行
- 不需要了解太深,如果你不是前端方向的,扫盲即可、
- 忘了没关系,边学边用边查!
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!
JS的讲解还未结束,下一篇文章将讲解JS的一些WebAPI,还有几个小项目
敬请期待!