【JavaScript】基础语法(二)

简介: JavaScript (简称 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

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:



         

内部什么规则,不需要懂

一般我们也不会让不同类型的在一个数组里


数组的截取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中没有继承,更没有多态

没有类,当然没有继承和多态

你最多能做的是,“嵌套对象”

目录
相关文章
|
4月前
|
存储 JavaScript 前端开发
Node.js的基本语法
【8月更文挑战第12天】Node.js的基本语法
137 1
|
2月前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
2月前
|
JavaScript 前端开发 大数据
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
30 0
|
4月前
|
JavaScript 前端开发
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
这篇文章是JavaScript基础与实战教程的第一部分,涵盖了JavaScript的基本语法、标识符、数据类型以及如何进行强制类型转换,通过代码示例介绍了JS的输出语句、编写位置和数据类型转换方法。
JavaScript基础&实战(1)js的基本语法、标识符、数据类型
|
4月前
|
前端开发 JavaScript 程序员
前端 JavaScript 的 _ 语法是个什么鬼?
前端 JavaScript 的 _ 语法是个什么鬼?
|
5月前
|
缓存 JavaScript 前端开发
前端框架与库 - Vue.js基础:模板语法、数据绑定
【7月更文挑战第14天】Vue.js 是渐进式框架,以简洁API和高效数据绑定知名。本文聚焦模板语法与数据绑定,解释常见问题和易错点,助力初学者避坑。模板语法中,{{ expression }} 用于渲染值,v-bind/: 用于动态绑定属性。数据绑定涉及文本、属性和事件,注意v-model适用于表单元素,计算属性有缓存。理解正确用法,借助文档和IDE,可提升开发质量和效率。善用Vue.js,打造响应式UI。
153 4
|
6月前
|
存储 JavaScript 前端开发
JavaScript 语法
JavaScript 语法
37 5
|
5月前
|
存储 JavaScript 前端开发
|
6月前
|
JavaScript 前端开发
JavaScript语法关键点:变量用`var`、`let`、`const`声明
【6月更文挑战第22天】JavaScript语法关键点:变量用`var`、`let`、`const`声明;七种数据类型包括`Number`、`String`、`Boolean`、`Null`、`Undefined`、`Symbol`和`Object`;运算符如算术、比较、逻辑和赋值;流程控制有`if...else`、`switch`和各种循环。了解这些是JS编程的基础。
62 3
|
5月前
|
前端开发 JavaScript
js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)
js【详解】Promise(含 Promise 的三种状态及其变化,创建 Promise, Promise.all 语法、Promise.all 实战范例、手写 Promise.all)
626 0