JavaScript 基础入门

一.JavaScript的由来

NetSpace公司在最初将其脚本语言命名为LiveScript ,后来NetSpace在与Sun 合作之后为了推广该语言,由于当时Java已经是十分流行的语言,并且是Sun公司开发的,因此NetSpace将其改名为JavaScript。

 

Script:脚本,手迹; 书写体铅字; 剧本、广播稿或者电影剧本;

JavaScript是一种脚本语言,Js的解释器就是JavaScript引擎,为浏览器的一部分。

JavaScript最初是由于以前网速很慢,所以NetSpace公司开发一种运行于浏览器中的语言,来进行一些表单验证判断,而现在Js几乎无所不能,如:

  • 网页特效
  • 服务端开发  (node.js)
  • 命令行工具  (node.js)
  • 桌面程序 (Electron)
  • 移动App (Cordova)
  • 控制硬件-物联网 (Ruff)
  • 游戏开发  (cocos2d-js)

 

二.JavaScript的组成

js有以下三部分组成:

 

1.ECMAScript ----一种脚本语言的语法标准

ECMA:欧洲计算机制造联合会

1995年Netscape发布的JavaScript大获成功,恰巧这时微软进军浏览器市场,IE 3.0搭载了一个JavaScript的克隆版-JScript, 再加上ScriptEase,导致了三种不同版本的客户端脚本语言同时存在。为了建立语言的标准化,1997年,在Netscape、Sun、微软、Borland等公司的参与下制订了ECMAScript 

从此以后的Javascript,JScript,ActionScript等脚本语言都是基于ECMAScript标准实现的。

所以,ECMAScript实际上是一种语言在语法和语义上的标准。在JavaScript,JScript和ActionScript中声明变量,操作数组等语法完全一样。但是在操作浏览器对象等方面又有各自独特的方法,这些都是各自语言的扩展。

 

2.BOM   ----浏览器对象模型(Browser Object Model)

一套操作浏览器功能的API

如通过BOM能操作浏览器窗口,弹出框,跳转,获得浏览器的分辨率等。。

 

3.DOM   ----文档对象模型(Document Object Model)

一套操作页面元素的API

DOM可以把HTML看成文档树,可以通过DOM提供的API来操作树上的节点

 

 

三.JavaScript的三种写法:

js写在哪里,在CSS中,讲过三种类型,js和css是一一对应的。

 

1.内联样式   ,直接写在html元素行内:

<img src="001.jpg" onclick="alert('123')"></img>

 

2.写在<script>标签中

css是写在style标签中,而js则是写在<srcript>中,如:

<script>
    alert('1');
</script>

 

3.外联样式

使用script的src属性,连接到外部的.js文件,src属性起到一个占位的作用

 <script src='js/index.js'></script>

js代码则写在js文件中。

 

注意:

1.建议使用第三种,外联样式,有助于结构分离

2.理论上来说<script>标签放在html文档的任何位置都可以,规范起见,推荐放到body结束标签的末尾,包含到body标签内,如:

1

2

3

4

<body>

    <!-- 这里是其他的HTML标签 -->

    <script> // 这里是代码 </script>

</body>

这样处理的好处是无需担心因页面未完成加载,造成DOM节点获取不到,使脚本报错的问题,而且能避免因脚本运行缓慢造成页面卡死的问题。

 

 

四.变量:

1.js中变量区分大小写

2.由于js是弱类型语言,所以没有int,string这种类型,定义变量一般使用var

var x;        //声明变量

var y=10;//声明并赋值

var s1,s2,s3;                       //同时声明多个变量

var s1=1, s2=2 ,s3=3;       //同时声明多个变量并赋值

3. 变量的命名遵循驼峰命名法(首字母小写,后面的大写):如userName,userPassword

 

五.数据类型

js中的基本类型有:Number,String,Boolean,Undefined , Null

 

1.Number类型:

整数:

var num=10;   //十进制整数

定义十六进制: 用0x前缀

int num =0xAB;

定义八进制: 用0前缀

int  num =017;

浮点数:

var result=0.1+0.2 ; 结果不是0.3

js中不要判断两个浮点数是否相等

如下图: 

 

如下图: 

  • 最小值:Number.MIN_VALUE
  • 最大值:Number.MAX_VALUE
  • 无穷大:Infinity
  • 无穷小:-Infinity

数值判断:

判断一个变量是否为Number类型可以使用IsNaN

IsNaN:  is not  a number

 

2.String类型

  • js可以使用单引号和双引号来表示字符串,推荐使用单引号
var  str = 'a' ; 
var  str1= "b" ;
  • js中使用反斜杠\ 来表示转义 
  • 用length来表示字符串长度:
var str='aaaaaa';
console.log(str.length);

js中拼接字符串使用

console.log('hello'+'world');

 

3.undefined 和null

undefined 表示一个声明了没有赋值的变量,变量只声明的时候默认是undefined

null 表示空,变量的值若想为null, 必须手动设置

如何定义:

//定义一个undefinity,只需声明就行
var  a;
console.log(a);

//定义一个null,需要手动设置
var b=null;
console.log(b);

打印结果如下:

 

4.复杂数据类型

Object

 

5.类型判断

类型判断的方法有很多:typeof, instanceof, constructor, prototype

typeof 的使用如下:

console.log(typeof 1 === 'number')      // => true
console.log(typeof 'wjh' === 'string')  // => true
console.log(typeof false === 'boolean') // => true
console.log(typeof [] === 'object')     // => true
console.log(typeof {} === 'object')     // => true
console.log(typeof null === 'object')   // => true
console.log(typeof un === 'undefined')  // => true

typeof 返回的结果是string类型的

typeof实际上是一个元运算符,所以不需要在typeof后面加上( ),但是加上也不会报错,也可以运行 

 

6.基本数据类型转换

1.转换成String类型

有两种方法toString() 和String() 

//toString()
var age=18;
console.log(age.toString());
var b= true;
console.log(b.toString());

//String()
var age=18;
console.log(String(age));
var b= true;
console.log(String(b));

注意:toString方法不可以判断undefinity和null,会报错,但是可以使用String() 来判断。

 

2.转化成数值类型

  • 使用Number() 方法:
var str='abc';
console.log(Number(str));   //  => NaN

var b=true;
console.log(Number(b);       //  => 1

var s='123';
console.log(Number(s));     //  => 123

var s1='123abv';
console.log(Number(s1));     //  => NaN

 

  • 使用parseInt()   //转换成int整数
parseInt(1) ;        //  => 1

parseInt('abc') ;  // => NaN

parseInt(true) ;    // => NaN

parseInt("123abc")   // =>123

parseInt方法无法将boolean类型转化成int

parseInt方法在遇到第一个非数字时,就停止运算,直接返回前面的值,如上例第四句

 

  • 使用parseFloat()   //转换成浮点数

跟parseInt十分相似,不同点在于:

parseFloat会解析第一个 . 遇到第二个 . 或者非数字则结束解析,直接返回

若解析内容为整数时,则解析成整数

 

  • 使用取正或者取负的方式转换成数值类型

这种方式是通过在执行+ - 时,自动将其他类型的值,转化成数值类型

如:

var  str='123';
console.log(+str);    // => 123

var str='456';
console.log(-str);   // => -456

var str='123abc';
console.log(+str);    // => NaN

var isOK=true;
console.log(+isOk);    // => 1

若有非数字,则转换失败,输出NaN

 

  • 使用减去零  - 0  的方式转化成数值类型

和上面的取正负类似,也是在执行运算的时候,将其他类型转换成数值类型,在做算术运算。

 

3.转换成布尔类型Boolean

使用Boolean() 方法 来转换成布尔类型

var str = 'abc';
var num = 123;
var a =null;
var b ;   //b为undefined

console.log(Boolean(str));  // true
console.log(Boolean(num));  // true
console.log(Boolean(a));  // false
console.log(Boolean(b));  // false

只有五种情况Boolean()方法 会将其他类型会返回false:
null    undefined    ' ' 空字符串   0    NaN

 

 

六.运算符

+  -  *  /   % 这些都是运算符

++a  和a++ 的区别

++a和a++ 都是表达式,都会返回一个值。

区别就是从左往右看,++a 是 把a+1  再返回  ;  而 a++ 则是先返回a ,再对a+1.

如:

var a=0;
console.log(a++);   //  0
console.log(a);     //  1

var b=0;
console.log(++b);   // 1
console.log(b);     // 1

 

== 和 ===的区别

简单来说: == 代表相同, ===代表严格相同

当进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行三等比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较

而三等比较时, 如果类型不同,直接就是false.

双等号==:

(1)如果两个值类型相同,再进行三个等号(===)的比较

(2)如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:

1)如果一个是null,一个是undefined,那么相等

2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较

三等号===:

(1)如果类型不同,就一定不相等

(2)如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)

(3)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。

(4)如果两个值都是true,或是false,那么相等

(5)如果两个值都引用同一个对象或是函数,那么相等,否则不相等

(6)如果两个值都是null,或是undefined,那么相等

 

七.数组

定义数使用中括号 [ ] :

var nums=[];  //定义空数组

var names=[1,2,3,5,6];
console.log(names[3]);   //  5

数组内的类型可以不一致:

var names=[ 1 , 'abc' , 1.2 , true];  //正确,但是不推荐这样使用

数组的长度用length 来获取

var names=[1,2,3,6];
console.log(names.length);   //  5

 修改数组中的值,可以直接赋值:

var names=[1,2,3,6];
names[0] = 100;

数组的长度可以动态改变,如:

var names=[1,2,3,4];
names[100] = 100;
console.log(names);

输出如下:

 

八.js代码后面的分号

建议写完一句代码后加分号,有些浏览器不加分号也不会报错,但为了代码稳定(解析出错)还是建议使用分号断句。

 

九.函数

 

1.定义函数用function

function functionName(parameters1,parameters2) {
  执行的代码
}

与C++,java不一样的是,js的函数没有public/private的修饰,也没有void/int的返回值修饰,也没有形参的void getMax(int x,int y) { } 这样的形参列表,而是直接写, 如 function  getMax( x , y ) {  }

//java的写法
prublic void getMax(int x,int y) { 
    .....
}

//js的写法
function  getMax( x , y ) {  
    .....
}

 

分号是用来分隔可执行JavaScript语句。
由于函数声明不是一个可执行语句,所以不以分号结束。

 

2.函数中的arguments

function sum()
{
    console.log(arguments[0],arguments[1]);
}

sum(2,4);

输出2,4

在任何函数内部都可以使用arguments这个对象,来取出实际传进来的参数

arguments非常想数组,但是不是数组

当参数固定时,建议使用形参表,当参数的个数不确定时,再使用arguments.

 

 

3.函数表达式(匿名函数 )

JavaScript 函数可以通过一个表达式定义。

函数表达式可以存储在变量中,如:

var x = function (a, b) {  return a * b  };

在函数表达式存储在变量x中后,变量也可作为一个函数使用,如:

var x = function (a, b) {return a * b};
var z = x(4, 3);

以上函数实际上是一个 匿名函数 。匿名函数和普通函数的区别就是少一个函数名称。

var x =function (parameters1,parameters2) {
  执行的代码
}

函数存储在变量中,不需要函数名称,通常通过变量名来调用。而且匿名函数不能单独写,必须要有一个变量来接。否则报错

 

正常的函数也能被储存在一个变量中:

var x = function sum(a, b) {  return a + b  };

但是呢,这样写没有实际的意义,因为已经可以函数已经有一个名字sum了,所以没有必要再加一个x变量来表示

 

4.自调用函数

通过上面第三点,我们知道一个函数可以被赋值到一个变量,然后通过该变量来实现调用,

那么如果不用一个变量来接这个函数的话,有什么方法能调用呢?

答案是可以使用自调用函数,如:

(function (){
    console.log('我是自调用函数');
})();

上面的代码等价于:

var x=function (){
    console.log('我是自调用函数');
};

x();

就是把一个函数用括号包起来,就相当于一个匿名变量了,然后再通过括号来调用该变量,也就是调用该函数。

 

5.函数也是一种数据类型

函数的类型为function,可以通过typeof 来输出函数的类型:

var fuc= function sum();
console.log(typeof fuc);

输出的值就是 function

 

6.函数也可以作为另一个参数和返回值

函数作为参数,如:

var fn =function() { console.log('我是一个传进来的函数');};

function test(fn){
    fn();
}

test(fn);

函数作为返回值,如:

var fn=function(){
    console.log('我是一个被返回的函数');
};

function test(fn){
    return fn;
}

var x=test(fn);
x();

 

7.全局作用域和局部作用域

全局作用域:

在script标签中或者在一个独立的js文件中定义的变量 就是全局变量,在任何位置都能访问。

局部作用域:

在任何函数的内部都有一个局部作用域,在函数内定义的变量,只有在函数内部才能访问。
在js中,局部作用域 就等于 函数作用域

 

8.ECMAScript没有块级作用域但是有函数作用域

我们知道在一般的编程语言中,都是有块级作用域的,既在一对花括号内定义的变量,无法在花括号外面访问。

如java:

  for(int i=0;i<10;i++)
	   {
		   int j=5;
	   }
System.out.println(j+"");

这是编译器会提示报错: j cannot be resolved to a variable

可见java是无法在块作用域外访问变量的。

但是js是可以的,如 :

function test(){
    for (var i = 0; i < 100; i++) {
    	var j=i;
    }
    console.log(j);
}

test();

输出99. 

可见,在块外,块中定义的变量i仍然是可以访问的。既在一个函数中的任何位置定义的变量在该函数中的任何地方都是可见的

也就是说,JS并不支持块级作用域,它只支持函数作用域,

那么我们该如何使JS拥有块级作用域呢?是否还记得,在一个函数中定义的变量,当这个函数调用完后,变量会被销毁,我们
否可以用这个特性来模拟出JS的块级作用域呢?看下面这个DEMO:

function test(){
	(function(){
    for (var i = 0; i < 100; i++) {
    	var j=i;
    }}) ();
    console.log(j);
}

test();

此时提示错误了:Uncaught ReferenceError: j is not defined

这正是在把一个代码断用() 包起来,成为另一个函数,然后实现自调用,自调用完毕后,会销毁该函数中的变量,因此实现了块作用域隔离

 

9.作用域链:

js只有两个作用域,就是全局作用域和函数作用域。

scpript标签开启了一个全局作用域,然后里面的函数1会开启一个函数作用域,这个函数1下面如果还定义函数2,那么会在

函数2中继续开启一个作用域,这样就形成了一个作用域链。

js解释器在寻找变量名称会在当前作用域找,然后一级级往上。如上就是先在函数2的作用域里找 j 变量,找不到在去函数1的作用域找,找不到再去全局作用域中找

 

 

 

十.预解析

跟C++的预编译一样,js在执行过程前,要进行预解析

预解析:

1.变量提升,把变量的声明(不包括赋值),把变量声明提升到当前作用域的最上面

2.函数提升,把函数的声明(不包括调用),把函数声明提升到当前作用域的最上面

之前我们分析了作用域,注意预解析是提升到当前作用域最上方

举例1:

console.log(num);
var num =10;

结果输出undefined.

按照上面的预解析流程:

1.首先找到所有的变量和函数的声明
2.找到了var num=10;
3.注意var num=10;这句话其实分为两部分,是声明+赋值,分别是var num; num =10;
4.然后把var num;这个声明提升到最上面,就只剩下了num=10;
5.然后其他代码原封不动,就变成下面这样了:

预解析后实际代码为:
var num;
console.log(num);
num= 10;

 

举例2:

f1();
function f1(){
    console.log('hello');
}
输出hello

跟上面同理:

预解析后实际代码为:

function f1(){
    console.log('hello');
}
f1();

 

举例三:

var a =25;
function abc(){
    alert(a);
    var a=10;
}
abc();


预解析过程:

1.找到所有变量的声明和函数的声明
2.找到了var a ;  提升到最上方,剩下a=25;不动
3.找到了function abc()的声明,然后把函数声明放到最上面就变成了这样:

var a ;
function abc(){
    alert(a);
    var a=10;
}
a=25;
abc();

4.继续,在abc函数中也要进行预解析,发现了var a=10;然后把var a; 提升到当前函数的最上方
5.最后预解析的结果为:

var a ;
function abc(){
     var a;   
     alert(a);
     a=10;
}
a=25;
abc();

所以按照js从上往下执行,会输出undefined

 

 

十一.对象

 

对象是什么?

之前的理解,对象就是Object,其他的对象都会继承Object类型,而Object类型通常会有toString ..等内置的方法。

对象是指包含一系列属性和方法的特殊的数据.

Object是一个对象,而且JavaScript 中的所有事物都是对象:字符串、数值、数组、函数... (除了null和undefined) ,他们都继承自Object

 

JavaScript 中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和复杂数据类型Object

那这不是冲突了吗,Number,String不是基本数据类型吗,他们和复杂数据类型Object不一样,那为什么又说他们也是对象呢,确实不一样,但是我们在使用的时候,js解释器会帮我们把Number,String,Boolean包装成对象,所以就有了万物皆对象,如果没有包装的Number,String,Boolean 并不是对象,只有包装后的才是对象。

 

创建对象的几种方式:

第一种,使用 { } 字面量创建

 var dog={
    	name:'jack',
    	type:'哈士奇',
    	age:'5',
    	color:'black',

    	eat:function(){
    		console.log(this.name+'啃骨头');
    	}
    }

    console.log(dog.name);
    console.log(dog.age);
    dog.eat();

js中对象用{ } 花括号来定义,在{ }中以键值对的形式,可以定义属性和方法

使用 对象名.属性名  的方式来访问属性,如 dog.name

还可以使用对象名[ ' 属性名 ']  的方式来访问属性,如 dog[ 'type' ]

数组是用  数组名[ 索引值],如array[0] 来访问第n个元素,而对象则是用 对象名[' 属性名'] 来访问属性

 使用  对象名.方法名()  的方式调用方法,如dog.eat

在对象中,定义方法的写法为 方法名: function (paramas ...)  {   }

而一般的函数写法为: function 方法名 (params ...) {  }

要注意区别

 

创建一个空对象

var a={ } :

 

2.用Object来创建:

person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
person.eyecolor="blue";

js中对象可以动态的添加属性和方法,如person.child='小明' ;这样就为person添加了一个属性。

 

3.使用自定义构造函数来创建:

function Person(name,age){
    this.name=name;
    this.age=age;
}

var ps=new Person('zs',24);

使用自定义函数来创建方法的要素有两点,第一必须有一个非匿名的函数,第二是使用new 关键字来创建。

 

 

js创建对象和c#的区别在于:

第一种方法,C#中不存在直接使用字面量创建对象的方式

第二种方法:C#中 var obj=new Object();也可以创建对象, 但是这个对象仅仅是object,虽然是其他对象的基类,但是不等于其他对象,而js中则可以动态的为该对象添加对象

第三种方法:C#中是使用class来定义一个对象A,然后在class中预先定义好属性和方法,然后使用A a=new A();来创建A对象.。 这种方法和第三种很像,只是形式不同,但是都是使用构造函数来创建.
js是使用function来代表普通函数,又可以代表构造函数,然后使用new 关键字来代表创建一个对象,而C#中则是使用class里面定义好的构造函数来构造.

 

var a=new Object();和var a={}有什么区别吗?

没有区别,两者都是生成一个默认的Object对象。
js和其它语言一样,一切对象的基类都是Object,所以,new Object()和简易的 { } 是同样的空对象,就是默认的对象
本来我以为{}应该是一个没有任何属性和方法的对象,但事实证明,var a = { };a.toString() 等Object对象所具有的方法,a都具有。
由此也可以判断,其实a = { }就是a = new Objcet()的简单实现。

 

 

遍历对象的属性:

var obj={
	name:'zs',
	age:18,
	func :function (){
		console.log(this);
	}
};


for(var key in obj)
{
	//key就是对象的成员的名字,为字符串形式
	//使用对象名['成员名'] 来访问对象的成员
	console.log(key +'---'+ obj[key] );
}

结果为:

 

使用delete来删除对象的属性和方法:

var obj={
	name:'zs',
	age:18,
	func :function (){
		console.log(this);
	}
};


console.log(obj.name);
console.log(obj.func);
delete obj.name;
delete obj.func;
console.log(obj.name);
console.log(obj.func);

输出结果为: 

 

 

 

 

十二. this

 

this代表的就是本身,但是在js中this在不同的地方有不同的含义

1.在函数中

一般的函数就是全局函数,那么this在全局函数中代表的是window,既当前窗体,如:

function func(){
   console.log(this);
}

func();

打印结果为:

 

2.在方法中

方法就是对象的成员函数,跟函数没什么区别,只是这个函数在对象中,所以称之为方法
在方法中,this指向的是该方法所属于的对象,如:

var obj={
	name:'zs',
	func :function (){
		console.log(this);
	}
};

obj.func();

打印结果为:

 

3.在构造函数中:

构造函数的写法和普通函数没有任何区别,只是约定构造函数的第一个字母大写

所以调用构造函数,若使用new来调用构造函数,则this指向的是构造的对象,若是使用普通的() 来调用的话,就是普通函数,既全局函数,那么this就是window,既第一种情况,如:

 
function Person()
 {
 	console.log(this);
 }
//用new关键字调用构造函数
var zs=new Person();

//使用()调用,则Person为普通函数,既全局函数
Person();

打印结果为:

 

打印了两个结果,第一个为Per'son,既要构造的对象,第二个为window 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值