Javascript基础学习个人笔记

这篇博客详细介绍了JavaScript的基础知识,包括变量声明、类型转换、算术运算符、逻辑运算符、关系运算符和函数的使用。还讨论了对象、作用域、this参数、构造函数、原型对象和数组的操作。内容涵盖了JavaScript的关键概念,如变量的声明、强制类型转换的规则、逻辑运算符的短路行为以及对象和函数的创建与使用。
摘要由CSDN通过智能技术生成

前言 :常用的输出语句
window.alert()——>写入提示框
document.write()——>写入html输出
console.log()——>写入浏览器控制台

一、JavaScript的变量

1.声明关键字var

与java和C不同,JavaScript不需要在声明时确定变量的数据类型。使用var定义的变量可以自适应任何赋予其中的数据类型。

<script>
	var a=6;
	console.log("a="+a);
	a="hello!"
	console.log("a="+a);
	a=true;
	console.log("a="+a);
</script>

结果:
在这里插入图片描述

二、强制类型转换

1.将其他类型转化为Number型

①使用Number()函数
null==>0;
boolean: true==>1,false==>0;
undefined==>NaN。

②使用parseInt()函数与parseFloat函数

  • 这两种函数都只有效于字符串中的第一串有效数字子串,例如parseInt(123.456)=123,parseFloat(123.456.789)=123.456。
  • 如果对非String类型变量使用parseInt()或parseFloat(),则会先对其使用toString()。
  • 不同的浏览器对于数字的进制解析不同,例如以下的一串代码
<script>
	var a = '070';
	a = parseInt(a);
	document.write(a);
</script>

在firefox、chrome中会显示70,而在老大IE版本种回被识别为八进制二显示成56。

P.S.
0X 八进制
0xX 十进制
0bX 二进制
解决方法:向parseInt中传入第二个参数,用来表示解析的进制数。如parseInt(“070”,8) = 56。

Tips
使用paeseInt()函数,能直接将小数转换为整数。

2.将其他类型转化为Boolean型

使用Boolean()函数:
Number ----> Boolean:除了0和NaN为false,其余全为true。
String ----> Boolean:除了空串为false,其余全为true。
null/undefined ----> Boolean:全为false。

三、算数运算符

1. “+”

① 与其他语言差不多,当Number类型与非Number类型(除String外)的值相加时,会将这些值先转化为Number然后再算,但需要注意的是任何值+NaN结果都为NaN。
② String类型的转化优先级较高,因此会将非String的值转化为String后做拼接操作。

Tips
针对这一特性,a = a + “” 就是toString的隐式转化式。

2. “-”,“÷”,"*"

① 除了"+"运算外,其余运算都会自动转化为Number类型。

  • 100 - “1” = 99。
  • “8” * 2 = 16。
  • undefined * 2 = NaN。

Tips
针对这一特性,a = a - 0 ,a = a / 1, a = a * 1就是number()的隐性类型转化式。

② 不同于C语言等常规语言,"/"会区分整数与浮点数。

  • 4 / 2 = 2
  • 3 / 2 = 1.5

3. “+”(正号),"-"(负号)

①负号可以对Number类型进行取反,对非Number类型的值,会先将其转化为Number类型后再进行取反。
②可以对一个数据类型使用+,来将其转化为Number类型。例如:

<script>
    // console.log('aaaa');
    var a = 1 + +"2" + 3;
    console.log(a);
</script>

结果则会在控制台输出一个类型为Number的6。

四、逻辑运算符

1. “&&”

JS中的&&运算符为短路运算符,例如:

<script>
    var a = 1 + +"2" + 3;//6
    console.log(a==0 && a++); // false
    console.log(a); //a = 6
</script>

在第一个输出语句中,&&运算符左边的等式返回false,由于短路原则不会执行右边的a++,故a依然为6。

2. “||”

JS中的||运算符为短路运算符,例如:

<script>
    var a = 1 + +"2" + 3;
    console.log(a!=0 || a++);//true
    console.log(a);//6
</script>

因此不推荐在逻辑运算符中加入其他赋值运算,如果可以的话,最好还是分开计算后再合并。

3. “&&”与“||”两边为非布尔值

①对非布尔值进行与、或运算时,会先将其转化为boolean类型,然后再运算,并且返回原值。
②与运算:

  • 如果第一个值为true,则必然返回第二个值。
  • 如果第一个值为false,则直接返回第一个值。
    P.S. 均返回原值!!!
<script>
    var a = 5 && 7;
    console.log(a);//7
    a = NaN && 0
    console.log(a);//NaN
</script>

③或运算与运算相反。

五、关系运算符

1. ‘<’,’>’,’<=’,’>=’

①对于非数字进行比较时,会将其转化为数字然后再比较。

  • 如果符号两侧的值都是字符串,不会将其转化为数字进行比较,而会逐次比较字符串中字符的Unicode编码。因此如果比较的是两个字符类型的数字的话,可能结果会不同,可以在前面加一个"+"转型。
  • 如果符号两侧有变量的值为NaN,则返回false。

2. ‘==’

①对于同类型的两个变量,若相等,则返回true,反之,返回false。
②对于不同类型的两个变量,在一般情况下,会将变量都转化为Number类型后在进行比较判断。以下列出几个特殊情况:

<script>
	console.log(null == undefined) //true
    console.log(null == 0); //false
    console.log(NaN == null); //false
    console.log(NaN == 0); //false
    console.log(NaN == NaN) //false
</script>

解析:NaN不和任何值相等,包括其自身。因此若想判断一个变量的值是否为NaN时,不能直接使用’==’,考虑调用函数isNaN()进行判断。

3. ‘!=’

①对于同类型的两个变量,若不等,则返回true,反之,返回false。
②对于不同类型的两个变量,可将其想象成"=="的逆操作,也就是说不同于C、JAVA等语言,当执行以下代码块时会自动进行类型的转换,之后再进行比较。

<script>
    console.log('1' != 1); //false
</script>

P.S.
若想实现C语言、Java语言中包括类型判断的相等与不等运算符,则可以使用"===“与”!= ="。

六、练习: 键盘输入方法-Prompt()函数

1.prompt()可以弹出一个提示框,用户可以在其中输入内容,该函数可添加一串字符串作为提示文字。函数会返回用户输入的内容。

<script>
	var age = prompt("请输入您的年龄~");
	alert("您的年龄为" + age + "岁");
</script>

七、函数

js的函数通过function关键字定义,与java和c不同,无论函数最后return什么数据类型都用function
<script>
	function myFunction(p1, p2) {
    	return p1 * p2;  // 返回 p1 和 p2 的乘积
	}
	alert(myFunction(2,6));
</script>

八、对象

对象可以看成一个可以包含多个值的变量,存储形式不同。

1.对象的基本操作

  • 普通定义:
var obj = new Object();
obj.name = "Klee";
obj.age = 12;
  • 定义的同时添加属性(对象字面量):
var person = {
	name:"Klee",
	age:8,
	gender:"女",
	eyeColor:"gold",
	sayname:function(){//在对象中封装函数时,这个函数成为这个对象的方法
		alert("I'm "+this.name);
	}
};

Tips
定义时名和值之间用冒号隔开,多个名值之间用逗号隔开,最后一个不加逗号。

  • 调用:person.sayname();
  • 删除:delete person.age;
  • 添加:person.age=12;
    P.S.
    如果要用特殊的属性名,不能用.的方式操作,则用[ ],且调用时也要用[ ]:
    person[“123”]=789;
    console.log(person[“123”]);
  • 检查对象中是否含有某个属性:console.log(“name” in person);
  • 枚举对象中的属性:
for (var n in person){
	alert("属性名"+n);
	alert("属性值"+person[n])//
}

P.S.
在for in语句枚举中,n在每次循环中会被赋予一个属性名,但是不能直接使用person.n来调用这个属性,因为对象中没有n这个属性,n只是被赋予了这个属性名的变量,他本身不是对象中的一个属性,要想使用这个变量n中的属性名,可以使用person[n]

2.对象的存储形式与变量的区别

  • 对象是保存在堆内存中的,每创建一个新的对象,就会在对内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个通过一个变量修改属性时,另一个也会受到影响。
  • 当比较两个基本数据类型时,就是比较值。当比较两个引用数据类型时,比较的是对象的内存地址

九、函数

函数也是对象,可以用来封装一些功能,以便在需要的时候调用执行。

1.函数的声明

function fun(){//直接用函数表达式声明
	alert("hello!");
}
var fun2=function(){//创建一个匿名函数再赋值给变量
	alert("hello!");
};

P.S.
上述两种函数的声明方式都可以使用,但是由于第二种利用了赋值语句所以在语句的最后要加上分号。

2.函数的参数

调用函数时可以向括号中传入参数

function sum(a,b){
	alert(a+b);
}
sum(23,3)

不同于java和C,实参可以是任意数据类型,甚至可以直接传入对象和函数。

var person={
	name:"Klee",
	gender:"女",
	age:18
}
function fun(o){
	alert("我是"+o.name+",今年我"+o.age+"岁");
}
fun(person);

3.函数的返回值

就是return,和大多数语言一样,唯一区别就是返回值可以是任意数据类型,这一点从定义函数时不需要设置返回值的数据类型可以看出。

4.立即执行函数

(function(){
	alert("我是一个匿名函数");
})();

匿名函数不能直接执行,除非放在括号里并再加上一对括号。立即执行函数往往只执行一次。

5.方法

在java和c中函数和方法往往是指同一个东西,在js中,方法是函数被封装在对象中时的称呼,不过这些也仅仅是名称上的区别。

var person = {
	name:"Klee",
	sayname:function(){//在对象中封装函数时,这个函数称为这个对象的方法
		alert("I'm "+this.name);
	}
};

Tips
对象里可以封装函数,函数里也可以添加对象。

十、作用域

作用域指一个变量的作用范围。作用域方面基本与java和c无异

1.全局作用域

  • 直接编写在script标签中的js代码,都在全局作用域里。
  • 全局作用域在页面打开时创建,在页面关闭时销毁。
  • 全局作用域中有一个全局对象window,我们可以直接使用。
  • 在全局作用域中创建的变量其实都会作为window对象的属性保存,创建的函数都会作为window对象的方法保存。
  • 全局作用域中的变量都是全局变量,在页面中的任意部分都可以被访问。
var a=10;
function fun(){
	alert("我是window的方法。");
}
alert(window.a);
window.fun();

2.函数作用域

  • 调用函数时创建函数作用域,函数执行完毕后,作用域销毁。
  • 每调用一次函数就会创建一个函数作用域,他们之间时互相独立的。
  • 函数作用域中可以访问全局作用域的变量
  • 在全局作用域中,无法访问函数作用域中的变量。

3.变量的声明提前

  • 使用var关键字声明的变量,会在所有的代码执行之前被声明。
alert(a);//a的声明会被提前到所有代码执行之前,但是a的赋值不会,故这里会输出undefined.
var a=10;

4.函数的声明提前

  • 使用关键词funtion创建的函数,会在所以代码执行前被声明并创建
  • 使用关键词var创建函数的话,则只会在所有代码执行前被声明。
fun();//输出“我是fun函数”
fun2();//输出undefined
function fun(){
	alert("我是fun函数");
}
var fun2(){
	alert("我是fun2函数");
}

十一、this参数

  • this是浏览器在调用函数时会向函数内部传递的一个隐含参数,this指向的是一个上下文对象。
  • 根据函数调用方式都不同,this可能会指向不同的对象。
    ①以函数的形式调用,this指向window;
    ②以方法的形式调用,this指向方法的那个对象。
    ③当以构造函数的形式调用时,this就是新创建的那个对象。
var name="Klee";
function fun(){
	alert(this.name);
}
fun();

上面代码中的以函数的形式调用fun(),实际上fun()是被封装到了window对象中,因此fun()相当于window.fun() ,故this指向window,所以this.name=window.name。

var person={
	name:"Klee"
	sayname:fun(){
		alert(this.name);
	}
};
person.fun();

上面的代码表示,以方法的形式调用fun(),this指向这个方法的对象,所以this.name=person.name。

十二、工厂方法

工厂方法批量创建对象。使用工厂方法创建的对象,使用的构造函数都是Object,导致无法区分多种不同类型都对象。
工厂方法实际使用较少。

function createPerson(name,age){
	var person = new Object();
	person.name = name;
	person.age=age;
	person.sayname=function(){
		alert(this.name);
	}
	return person;
}
var obj=createPerson("Klee",12);
var obj2=createPerson("Abor",15);

十三、构造函数

1.基础概念

  • 构造函数也是用来创建对象的,比较常用。
  • 构造函数就是一个普通函数,创建方式与普通函数没有区别,区别在于调用方法的不同,而且通常习惯用首字母大写的函数名。
  • 普通函数直接调用,而构造函数需要用new关键字调用。
  • 构造函数的执行流程:
    1.立刻创建一个新的对象
    2.将新建的对象设置为函数中的this,在构造函数中可以使用this来应用新建的对象。
    3.逐行执行函数中的代码
    4.将新建的对象返回
function Person(name,age){
	this.name=name;
	this.age=age;
}
var per = new Person("Klee",12);
var per2= new Person("Abor",18);
alert("per的名字="+per.name);
alert("per2的名字="+per2.name);
  • 使用instanceof可以检查一个对象是否是一个类的实例
alert(per instanceof Person);//true

P.S.
用java 的术语来讲,构造函数就是类,构造函数创建的对象就是该类的实例。

2.改进方法

  • 在第一点中有提到,每创建一个构造方法就会创建一个新的对象,那么看下面的代码
function Person (name){
	this.name = name;
	this.sayName = function(){
		alert("Hello大家好,我是"+this.name);
	};
}

用这个构造函数创造的所有对象都会有一个完全一样的sayName方法,这样太过冗余,我们可以按照下面的代码来改进这个构造函数。

//sayName方法在全局作用域中定义,但是不安全可能会被其他程序员覆盖
function fun(){
	alert("Hello大家好,我是"+this.name);	
}
function Person(name){
	this.name = name;
	this.sayName = fun;
}

十四、原型对象

1.概念

每创建一个函数,浏览器都会向函数中添加一个属性prototype,即是原型对象。
当这个函数被当做构造函数调用时,它所创建的对象中会有一个隐含的属性,指向构造函数的原型对象,我们可以通过__proto__来访问该属性。

function MyClass(){
}
var mc = new MyClass();
alert(mc.__proto__ == MyClass.__proto__);//true

2.作用

  • 原型对象相当于一个公共区域,同一个构造函数创造的对象都可以访问,我们可以将对象共有的内容设置到原型对象中。
  • 访问对象中的属性时,它会优先在对象自身中寻找,如果没有找到则会去原型对象中寻找。
    有了这个公共区域,我们可以继续优化构造函数了。
function Person(name){
	this.name = name;
}
//向构造函数的原型中添加sayName方法
Person.prototype.sayName = function(){
	alert("Hello大家好,我是:"+this.name);
};

以后创建构造函数时,可以将对象共有的属性和方法,添加到原型对象中,这样不用分别为每一个对象添加,也不会影响全局作用域。
P.S.
原型对象的共有性质可以简单类比java中的父类,子类都继承父类的属性和方法,而且这些继承下来的东西可以被重写
Tips
上面提到过,调用构造函数构造的对象中的属性时,若这个对象中没有该属性,则会去原型对象中寻找并使用,这对in关键字查询对象中是否有某个属性时也是一样的。如果想要知道这个对象本身是否含有一个属性,而不考虑原型对象的话,应该使用对象.hasOwnProperty()函数:

function MyClass(){
}
MyClass.prototype.name="我是原型中的名字";

var mc = new MyClass();

alert("name" in mc);//true
alert(mc.hasOwnProperty("name"));//false

这个hasOwnProperty()函数来自原型对象中的原型对象,原型对象也是对象,所以它也有原型。不过这个套娃到此为止,不存在原型的原型的原型了,也就是Object对象的原型没有原型了。

function MyClass(){
}
var mc = new MyClass();
alert(mc.__proto__.hasOwnProperty("hasOwnProperty"));//false
alert(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//true,这个函数就在原型的原型里
alert(mc.__proto__.__proto__);//Object存在
alert(mc.__proto__.__proto__.__proto__);//null不存在

十五、toString()

1.概念

  • 当我们直接在页面中打印一个对象时,事实上是输出对象的toString()方法的返回值。
  • 这个方法其实在对象的原型的原型里,也就是在Object对象里。
function Person(name ,age){
	this.name = name;
	this.age = age;
}
var per = new Person("Klee",12);
//如果我们希望输出对象时不输出[objec Objec],可以为对象重写一个toString()方法,per.toString=function(){}如此,不过如果希望由此构造函数创建的所有对象都享受到这个重写,则应这样写:
Person.prototype.toString = function(){
	return "[name="+this.name+",age="+this.age+"]";
};
alert(per);

十六、数组

1.数组对象的基本操作

  • 创建:var arr = new Array();
  • 语法:arr[索引] = 值;
  • 获取数组长度:arr.length
  • 向数组的最后添加值:arr[arr.length] = 值;

2.使用字面量创建数组

var arr = [2,4,7,5,9];
console.log(arr.length);//5

//很少用
var arr2 = new Array(10);//这样使用构造函数创建一个长度为10的数组

3.元素

数组的元素可以是任意类型

//甚至可以放对象,函数,数组
var arr = ["hello",2,true,{name:"Klee",age:12},function(){}[1,2,3]];

4.主要方法

  • push()方法向数组末尾添加一个活多个元素并返回数组新的长度。
  • pop()方法删除数组的最后一个元素,并返回被删的元素。
var arr = [12,3,43];
var len = arr.push(23,43);
console.log(arr);//12,3,43,23,43
alert(len);//5
var re = arr.pop();
console.log(re);//43
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值