JavaScript是一种属于网络的脚本语言,常用来为网页添加各式各样的动态功能,是一种动态类型、弱类型、基于原型的语言。
它包括三个部分:ECMAScript、BOM和DOM。ECMAScript描述了该语言的语法和基本对象。BOM,浏览器对象模型,描述了与浏览器进行交互的方法和接口。DOM,文档对象模型,描述了处理网页内容的方法和接口。
js的使用:js代码写在script标签中,其引入方式和css样式的style标签一致。

一、变量、数据类型与运算符

  1.变量

  声明变量

- 通过var关键字声明一个或多个变量。
  - 声明变量的同时可以给其赋值(直接量,字面量),也可以不赋值,不赋值时默认值为undefined。
  - 变量命名遵循一般的命名规范:区分大小写,不能包含特殊字符,大小驼峰命名或下划线命名,不能以数字开头,命名含义明确等。
  - 变量在内存中会自动存储于释放。

  2.数据类型

js中的数据类型包括:字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined)。

  隐式转换

// 转换为布尔类型
var a; // undefined.
var test = function(vec){
if(vec){
console.log("true");
}else{
console.log("false");
}
};
a = null;
a = 0; // 0值
a = NaN; // NaN值
a = ''; // 空字符串
test(a);
// 转换成数值型数据
var a;// undefined -> NaN
var b = 1;
a = null; // null -> 0
a = false; // false -> 0
a = "123"; // "12" -> 12
a = "123abc"; // "123abc" -> NaN
console.log(typeof a);
console.log(b + a);

  强制转换

// parseInt(string):将字符串类型转换成数值;
// parseFloat(string):将字符串类型转换成浮点型数值;
var a = "123";
console.log(typeof parseInt(a));
console.log(typeof parseFloat(a));
// String()和toString():将其它类型转换成字符串
var a = 123;
console.log(typeof String(a));
console.log(typeof a.toString());
// Boolean:将其它数据类型转换成布尔值。;
var a = undefined;
console.log(Boolean(a), typeof Boolean(a));

  3.运算符

  1.算术运算符

+、-、*、/、%、++、--
++、--分为前缀形式和后缀形式。前缀先自加(减)再执行运算,后缀先执行运算再自加(减)。

  2.赋值运算符和比较运算符

=、+=、-=、*=、/=、%=、.=
>、>=、<、<=、==、!=、===、!==

  3.逻辑运算符

&&、||、!

  4.三元运算符

// exp1?exp2:exp3
var a = 1231; // var a;
typeof a==="number"?console.log("true"):console.log("false");

  5.运算符优先级

运算符 描述
. [] () 字段访问、数组下标、函数调用以及表达式分组
++ -- - ~ ! delete new typeof void 一元运算符、返回数据类型、对象创建、未定义值
* / % 乘法、除法、取模
+ - + 加法、减法、字符串连接
<< >> >>> 移位
< <= > >= instanceof 小于、小于等于、大于、大于等于、instanceof
== != === !== 等于、不等于、严格相等、非严格相等
& 按位与
^ 按位异或
| 按位或
&& 逻辑与
|| 逻辑或
?: 条件
= oP= 赋值、运算赋值
, 多重求值

二、流程控制

  1.条件语句

// if(exp){执行代码段};
var a = 123; // var a;
if(typeof a === "number"){
console.log("true");
}
// if(exp){exp为true的代码段}else{exp为false的代码段};
var a = 123; // var a;
if(typeof a === "number"){
console.log("true");
}else {
console.log("false");
}
// if ... else if ...
var readline = require("readline");
var rl = readline.createInterface({
input: process.stdin,
out: process.stdout,
});
rl.question("请输入成绩: ", (number) => {
if(number > 100){
console.log("输入的成绩不能大于100!");
}else if(number > 80){
console.log("录入成功,A档");
}else if(number > 60){
console.log("录入成功,B档");
}else if(number > 0){
console.log("录入成功,C档");
}else{
console.log("输入的成绩不能小于0!")
}
rl.close();
});
rl.on("close", function () {
console.log("退出程序!");
process.exit();
});
var readline = require("readline");
var rl = readline.createInterface({
input: process.stdin,
out: process.stdout,
});
rl.question("请输入星期几: ", (day) => {
switch(day){
case "1":
console.log("今天吃炒面");
break;
case "2":
console.log("今天吃鱼香肉丝");
break;
case "3":
console.log("今天吃麻辣香锅盖饭");
break;
case "4":
console.log("今天吃豆丁胡萝卜");
break;
case "5":
console.log("今天公司聚餐");
break;
case "6":
console.log("今天吃泡面");
break;
case "7":
console.log("今天撸串");
break;
default:
console.log("input error.")
} rl.close();
});
rl.on("close", function () {
process.exit();
}
// switch ... case ...
var readline = require("readline");
var rl = readline.createInterface({
input: process.stdin,
out: process.stdout,
});
rl.question("请输入星期几: ", (day) => {
switch(day){
case "1":
console.log("今天吃炒面");
break;
case "2":
console.log("今天吃鱼香肉丝");
break;
case "3":
console.log("今天吃麻辣香锅盖饭");
break;
case "4":
console.log("今天吃豆丁胡萝卜");
break;
case "5":
console.log("今天公司聚餐");
break;
case "6":
console.log("今天吃泡面");
break;
case "7":
console.log("今天撸串");
break;
default:
console.log("input error.")
} rl.close();
});
rl.on("close", function () {
process.exit();
});

  2.循环语句

  for 循环

和java中的for循环一致:for(exp1; exp2; exp3){代码块;}
  - exp1: 无条件的执行第一个表达式
  - exp2: 是判断是否能执行循环体的条件
  - exp3: 增量操作
// 九九乘法表
var str = "";
for(var i=1;i<=9;i++){
for(var j=1;j<=i;j++){
str += i + "*" + j + "=" + i*j + " ";
if(i === j){
str += "\n";
}
}
}
console.log(str);

  while 循环

var arr = function (number) {
var arr_list = new Array(); // var arr_list = [];
var i = 0;
while (i < number){
arr_list[i] = Math.random();
i++;
}
return arr_list;
};
console.log(arr(5))
var arr = function (number) {
var arr_list = new Array(); // var arr_list = [];
var i = 0;
while (i < number){
arr_list[i] = Math.random();
i++;
}
return arr_list;
};
console.log(arr(5));

  do ... while循环


// 和java中的do ... while 循环一致,先执行依次do内的代码块,再执行while 判断。不管while条件判断是否成功,do都会至少执行一次。
var arr = function (number) {
var arr_list = new Array(); // var arr_list = [];
var i = 0;
do {
arr_list[i] = Math.random();
i++;
}while (i > number);
return arr_list;
};
console.log(arr(5));

三、函数

  1.定义

  函数通过function关键字定义。function 函数名称([参数1, ...]){代码块; [return 返回值]};也可以通过Function构造器定义函数。


// 通过function 关键字定义函数
function hello() {
console.log("hello world.")
};
hello();

  匿名函数,即function关键字定义的无函数名称的函数。

// 通过function 关键字定义匿名函数
var hello = function () {
console.log("hello world.")
};
hello();

  将匿名函数作为参数,传递给另一个函数进行执行,此时其被称为回调函数。回调函数在js中异常强大。

function calc(v1, v2, callback) {
v1 = v1 || 1;
v2 = v2 || 2;
return callback(v1, v2);
}
calc(3,4, function (v1, v2) {
return v1 + v2
});

  

  2.参数

  函数如果定义了参数,在调用函数的时候没有传值则默认值为undefined。如果传递的参数超过了形参,js会忽略掉多于的参数值。

function  calc(v1, v2){
return v1 + v2;
}
console.log(calc(5, 6, 7));

  es5不能直接写形参的默认值,但可以通过arguments对象来实现默认值。同时,arguments对象可以实现可变参数。

function  calc(v1, v2){
v1 = v1 || 1;
v2 = v2 || 2;
return v1 + v2;
}
console.log(calc());

  3.函数调用

function calc(v1, v2, callback) {
v1 = v1 || 1;
v2 = v2 || 2;
return callback(v1, v2);
}
value1 = calc(3,4, function (v1, v2) {
return v1 + v2
}); value2 = calc.call(calc, 3, 4, function (v1, v2) {
return v1 + v2;
}); value3 = calc.apply(calc, [3, 4, function (v1, v2) {
return v1 + v2;
}]); value4 = (function (v1, v2) {
return v1 + v2;
})(3, 4);
console.group("函数调用的方式");
console.log("- 直接调用: " + value1);
console.log("- 间接call调用: " + value2);
console.log("- 间接apply调用: " + value3);
console.log("- 自调用: " + value4);

四、对象

  js中对象分为:内建对象、宿主对象和自定义对象。

  1.对象创建

  直接通过var关键字定义Object对象。

var obj1 = new Object();
var obj2 = {};
// 使用字面量来创建一个对象: var obj = {} 和new本质上是一模一样的
// 使用字面量创建对象时,可以在创建对象时直接指定对象中的属性
// 字面量里面的属性可以加引号,也可以不加引号,建议不加
// 如果使用特殊字符或名字则必须加引号
var obj = {
name: "孙悟空",
gender: "男猴",
age: 1500,
credit: {
name1: "孙行者",
name2: "齐天大圣"
}
};
console.log(obj);

  也可以通过工厂方法创建对象。

function Person(name, age) {
var obj = {};
obj.name = name;
obj.age = age;
obj.sayHello = function () {
console.log(obj.name + ", " + obj.age + "years old.");
};
return obj;
}
sun = Person("孙悟空", 2000);
sun.sayHello();

  2.对象属性操作和方法创建


var obj = new Object(); // new 构造对象, 可使用typeof obj 查看对象
// 在对象中保存的值称为属性
// 向对象中添加属性:对象.属性名 = 属性值
obj.name = "孙悟空";
obj.gender = "男猴";
obj.age = 18;
console.log(obj);
// 读取对象中的属性: 对象.属性名
// 如果读取的对象中没有该属性,会返回undefined
console.log(obj.name);
// 修改对象的属性值: 对象.属性名 = 新值
obj.age = 24;
console.log(obj);
// 删除对象属性
delete obj.age;
console.log(obj);
// 自定义
obj.fuc = function add(x, y) {
return x+y;
};
console.log(obj);

  3.作用域

在js中一共有两种作用域,全局作用域和函数作用域
全局作用域:
- 直接编写在script标签内的JS代码
- 在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,可以直接使用.它代表的是一个浏览器的窗口,它由浏览器创建
- 在全局作用域中创建的变量都会作为window对象的属性保存
- 在全局作用域中创建的函数都会作为window对象的方法保存
- 全局作用中的变量和函数在页面的任意位置都可以被访问/执行
  函数作用域:
  - 调用函数时创建函数作用域,函数执行完毕之后,函数作用域销毁
  - 每调用一次函数就会创建一个新的函数作用域,它们之间是相互独立的
  - 全局作用域中访问不到函数作用域,函数作用域中可以访问全局作用域
   - 函数作用域会优先查找本作用域中的变量,如果没有就找上一级中的变量
  - 函数作用域的a并不影响上一级作用域中的a
- 如果不使用var声明,直接写a = 20,就是在操作全局作用域中的a变量
- 如果使用全局作用域中的a变量[在本作用域中已声明a变量],可以用window.a,这在b1中已强调过

  全局作用域

console.log(window); // window是个对象

// 使用var关键字声明的变量,会在所有的代码执行之前执行;如果声明变量时不使用var,则变量不会被提前声明
console.log(a); // 此时的var a已被声明,它的值是undefined,到下一行时它的值才会是123 var a = 123; // 它相当于window.a = 123
console.log(window.a); console.log(abc()); // 可以提前声明和执行
console.log(abc2()); // var提前声明的是一个undefined的window属性,不是个函数: abc2 is not a function // 使用function关键字声明的函数,和var的机制一样,是函数声明的提前,它会提前(优先)执行
function abc() { // 它相当于window.abc = function (){console.log("abc")}
console.log("abc");
}
console.log(window.abc()); // 使用函数表达式不会被声明提前
var abc2 = function() {
console.log("abc2");
}

  局部作用域

var a = 19;
var b = 30;
function fun() {
a = 20;
var b = 1000;
console.log("a = " + a); // 这里打印的是20
console.log("b = " + b); // 这里打印的是1000
console.log("window.b = " + window.b); // 这里打印的是30
}
fun();
console.log(a); // 这里打印的是20
// 定义形参相当于在函数作用域中声明了变量

五、原型

  1.this关键字

解析器在调用函数时,会向函数内部传递进一个隐含的参数这个隐含的参数就是this,this指向的是一个对象,这个对象称为函数执行的上下文对象
根据函数的调用方式不同,this会指向不同的对象
- 1.以函数的形式调用时,this永远都是window
- 2.以方法的形式调用时,this就是调用方法的那个对象
var name = "全局名字";
function func(a, b) {
console.log("a = " + a + ", b = " + b);
console.log(" Object: " + this);
console.log(this);
}
func(123, 456); // this指的是window
function func2() {
console.log(this.name);
console.log(this);
}
var obj = {
name: "孙悟空",
sayName: func, // 把函数赋给属性,this指的是obj
sayName2: func2 };
var obj2 = {
name: "猪八戒",
sayName: func, // this指的是obj2
sayName2: func2
};
obj2.sayName(2332, 4523);
obj.sayName(234, 789);
obj.sayName2(); // this可以支持对象内部的函数去访问对象内部的属性
obj2.sayName2(); // 这一点特别像python类中的self

var obj3 = {
name: "沙和尚",
teacher: "唐僧",
address: "流沙河",
sayMyTeacher: function3,
sayMySelf: function2,
say: function1
};
function function1() {
var say = this.sayMySelf() + this.sayMyTeacher();
console.log(say);
}
function function2() {
var say = "大家好,我是" + this.name + ",我老家是" + this.address;
return say
}
function function3() {
var say = "。我的师父是" + this.teacher + "老师, 他是个得道高僧";
return say
}
obj3.say();

  2.构造方法的重写


function Person1(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
// this.sayName = function() {
// console.log("大家好,我系" + this.name); // 这样写每创建一个对象,就会创建一个sayName
// }
this.sayName = sayName; // 共用同一个方法,它就相当于python中的类方法[类方法只有一份,但每个实例对象都共用]
} // 注意这里的写法,一个隐含的this传递给了sayName函数
var per1 = new Person1("孙悟空", 18, "男");
per1.sayName(); // 在全局作用域中写sayName
// 但是它污染了全局作用域的命名空间,也就是全局作用域不能再写sayName函数
// 另外这个函数也很不安全,由此引出了"原型"的概念
function sayName() {
console.log("大家好,我系" + this.name);
}

  3.原型

  1.原型prototype

我们所创建的每一个函数,解析器都会向函数中添加一个属性:prototype
如果函数作为普通函数调用prototype,没有任何作用
当该函数以构造函数的形式调用[per1]时,它[per1]会有一个隐含的属性__proto__指向其原型对象[Person]
每次调用时都会有各自的__proto__指向原型对象的prototype,也就是原型对象中的属性和方法被调用函数"共享"
function Person() {}
console.log(Person.prototype); var per1 = new Person();
console.log(per1.__proto__ == Person.prototype); // true Person.prototype.a = "我是原型对象中的123456";
per1.a = "我是mc中的" +"123456"; var per2 = new Person();
console.log(per1.a); // 找到调用函数的属性和方法,直接执行
console.log(per2.a); // 如果调用函数没有该属性或方法,会从原型对象中寻找 Person.prototype.sayName = function() {
console.log('我是原型对象的sayName');
};
per2.sayName = function() {
console.log('我是per2中的sayName');
};
per1.sayName(); // 和前面的类似
per2.sayName(); // 和前面的类似
// 解决全局作用域污染问题: 把对象的函数写在prototype里而不是全局作用域里
function MyPerson(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
MyPerson.prototype.sayName = function() {
console.log("大家好,我系" + this.name);
};
var mp1 = new MyPerson("孙悟空", 2000, "男猴");
mp1.sayName();

  2.原型模拟类和对象

  在python中声明一个类和对象:

class Person(object):
  def __init__(self, name, age):
    self.name = name
    self.age = age
  def sayHello(self):
    print("{}, {} years old.".format(self.name, self.age)) sun = Person("孙悟空", 2000)
sun.sayHello() // 对象可以调用方法,因为方法只有一份且存在类内存中,每个对象只保留了引用
Person.sayHello(sun) // 类可以传入一个对象来调用方法,因为方法存在类内存中

  在Java中创建一个类和对象:类的方法存在方法区,对象存在堆内存中,多个对象共用它们父类的方法。它需要设置静态方法来实现对象调用。

public class Person {
private String name;
private int age;
Person(String name, int age){
  this.name = name;
  this.age = age;
  }  
  public void sayHello(){
  System.out.println(this.name + ", " + this.age + "years old.");
  }
  public static void sayHello(Person obj){
  System.out.println(obj.name + ", " + obj.age + "years old.");
  }
  public static void main(String[] args){
  Person sun = new Person("孙悟空", 2000);
  Person.sayHello(sun);
  sun.sayHello();
  }
}

  在js中,对象保存在堆内存中,每创建一个新的对象都会开一个堆内存空间,并把其属性和方法都保存在堆内存中。注意,如果不用原型,每个对象都会将其方法复制一份到自己的堆内存空间中。js中实现类调用实例对象:

function MyPerson(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
MyPerson.sayName = MyPerson.prototype.sayName = function (obj) { // 在自己的prototype空间里写函数
obj = obj || this;
console.log("大家好,我系" + obj.name + ", 一只火眼金睛的" + obj.gender); // 让每个实例都能访问
}
}
var mp1 = new MyPerson("孙悟空", 2000, "男猴"); // 注意这里使用的是new MyPerson,构造
mp1.sayName();
MyPerson.sayName(mp1);

前端(三):JavaScript基础的更多相关文章

  1. 第三篇:web之前端之JavaScript基础

    前端之JavaScript基础   前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript ...

  2. 前端之JavaScript基础

    前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...

  3. 前端见微知著JavaScript基础篇:你所不知道的apply, call 和 bind

    在我的职业生涯中,很早就已经开始使用JavaScript进行项目开发了.但是一直都是把重心放在了后端开发方面,前端方面鲜有涉及.所以造成的一个现象就是:目前的前端知识水平,应付一般的项目已然是足够的, ...

  4. 前端-JavaScript2-1——JavaScript基础复习及上次作业答案

    昨天讲解的JS是编程最最简单的一些基础知识,复习一下: JavaScript书写环境,<script>标签 1    <script type=”text/javascript”&g ...

  5. 谷哥的小弟学前端(10)——JavaScript基础知识(1)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 具体解释Android主流框架不可或缺的基石 站在源代码的肩膀上全解Scroller工作机制 Android多分辨率适 ...

  6. 前端之JavaScript基础及使用方法

    JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...

  7. 前端见微知著JavaScript基础篇:this or that ?

    上节,我们提到了this关键字的问题,并且追加了一句很有意义的话:谁调用我,我指向谁.的确,在javascript中,在默认情况下,this会指向一个已经初始化的window对象.所以你不论有多少全局 ...

  8. 前端--关于javascript基础

    首先javascript不是浏览器的附属品,只能说它大多数的运行环境是在浏览器中的,但又不仅仅局限于浏览器中.它是一门真正的程序设计语言,在这方面它和java.c.c++.c#是等同的,只不过它不直接 ...

  9. 谷哥的小弟学前端(11)——JavaScript基础知识(2)

    探索Android软键盘的疑难杂症 深入探讨Android异步精髓Handler 具体解释Android主流框架不可或缺的基石 站在源代码的肩膀上全解Scroller工作机制 Android多分辨率适 ...

  10. Web前端开发JavaScript基础

    JavaScript 一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型,它的解释器被称为JavaScript引擎,是浏览器的一部分,并且是被广泛用于客户端的脚本语言,JavaS ...

随机推荐

  1. 五,Smarty模板技术/引擎——自定义函数机制

    自建函数是smarty提供的函数,不允许修改,只能被调用: 自定义函数是自己编写函数,注册成为smarty的函数,之后可以被调用: 示例:使用smarty自定义函数的机制,编写一个函数myfun1,通 ...

  2. jvm内存分部

    首先我们必须要知道的是 Java 是跨平台的.java常用的名词有jdk,jre,jvm jdk包括后两者,是开发者工具集, jre表示java运行环境, jvm是java虚拟机,是java夸平台的保 ...

  3. ORM查询练习

    ORM查询练习 Django ORM  ORM查询的练习题 ORM代码 from django.db import models # Create your models here. class Pu ...

  4. EPC sequence

    nps-epc-term-2.7.0 eNodeB: /root/b2b/eutran/01/bin ./clean_log.sh ./set_ip.sh [root@CEN6- bin]# ./cl ...

  5. 完美解决读取Excel的数字单元格时Cannot get a STRING value from a NUMERIC cell 报错处理

    我使用的是Poi(最新的4.1.0)方式读取Excel ,我的方法如下: 在打印cell内容时,抛出下面的错误 Exception in thread "main" java.la ...

  6. maven打包时跳过测试类

    记录 修改pom.xml文件 <project> [...] <build> <plugins> <plugin> <groupId>org ...

  7. cloudera-scm-server启动时出现Caused by: javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Could not open connection问题解决方法(图文详解)

    问题现象 查看 [root@cmbigdata1 cloudera-scm-server]# pwd /var/log/cloudera-scm-server [root@cmbigdata1 clo ...

  8. 案例16-validate自定义校验规则校验用户名是否存在

    1 知识点 2 register.jsp代码 注意自定义校验规则的时候,提交必须是同步的方式. <%@ page language="java" contentType=&q ...

  9. 【CSS】 布局之多列等高

    这两天看了不少文章,对于css布局多了一些理解,现在来总结下. 我们来写一个最普遍的Top.Left.Content.Right.Foot布局. 第一步:自然是写一个坯子 <!DOCTYPE H ...

  10. 栈C++实现

    栈的核心是LIFO(Last In First Out),即后进先出 出栈和入栈只会对栈顶进行操作,栈底永远为0.如果是入栈,要将入栈元素赋值给栈数组,再将栈顶上移一位:出栈时要先将栈顶下移一位,再将 ...