2020-01-20

JavaScript 函数定义

JavaScript 使用关键字 function 定义函数。

函数可以通过声明定义,也可以是一个表达式。

函数声明

function functionName(parameters) {

  执行的代码

}

函数声明后不会立即执行,会在我们需要的时候调用到。

实例

function myFunction(a, b) {

    return a * b;

}

分号是用来分隔可执行JavaScript语句。

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

函数表达式

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

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

实例

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

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

实例

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

var z = x(4, 3)

以上函数实际上是一个 匿名函数 (函数没有名称)。

函数存储在变量中,不需要函数名称,通常通过变量名来调用。

上述函数以分号结尾,因为它是一个执行语句。

Function() 构造函数

在以上实例中,我们了解到函数通过关键字 function 定义。

函数同样可以通过内置的 JavaScript 函数构造器(Function())定义。

实例

var myFunction = new Function("a", "b", "return a * b");

var x = myFunction(4, 3);

实际上,不必使用构造函数。上面实例可以写成:

实例

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

var x = myFunction(4, 3);

在 JavaScript 中,很多时候,需要避免使用 new 关键字。

函数提升(Hoisting)

提升(Hoisting)是 JavaScript 默认将当前作用域提升到前面去的的行为。

提升(Hoisting)应用在变量的声明与函数的声明。

因此,函数可以在声明之前调用:

myFunction(5);

function myFunction(y) {

    return y * y;

}

使用表达式定义函数时无法提升。

自调用函数

函数表达式可以 "自调用"。

自调用表达式会自动调用。

如果表达式后面紧跟 () ,则会自动调用。

不能自调用声明的函数。

通过添加括号,来说明它是一个函数表达式:

实例

(function () {

    var x = "Hello!!";      // 我将调用自己

})();

以上函数实际上是一个 匿名自我调用的函数 (没有函数名)。

函数可作为一个值使用

JavaScript 函数作为一个值使用:

function myFunction(a, b) {

    return a * b;

}

var x = myFunction(4, 3);

JavaScript 函数可作为表达式使用:

实例

function myFunction(a, b) {

    return a * b;

}

var x = myFunction(4, 3) * 2;

函数是对象

在 JavaScript 中使用 typeof 操作符判断函数类型将返回 "function" 。

但是JavaScript 函数描述为一个对象更加准确。

JavaScript 函数有 属性 和 方法。

arguments.length 属性返回函数调用过程接收到的参数个数:

实例

function myFunction(a, b) {

    return arguments.length;

}

toString() 方法将函数作为一个字符串返回:

实例

function myFunction(a, b) {

    return a * b;

}

var txt = myFunction.toString();

函数定义作为对象的属性,称之为对象方法。

函数如果用于创建新的对象,称之为对象的构造函数。

箭头函数

ES6 新增了箭头函数。

箭头函数表达式的语法比普通函数表达式更简洁。

(参数1, 参数2, …, 参数N) => { 函数声明 }

(参数1, 参数2, …, 参数N) => 表达式(单一)

// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }

当只有一个参数时,圆括号是可选的:

(单一参数) => {函数声明}

单一参数 => {函数声明}

没有参数的函数应该写成一对圆括号:

() => {函数声明}

实例

// ES5

var x = function(x, y) {

    return x * y;

}

// ES6

const x = (x, y) => x * y;

有的箭头函数都没有自己的 this。 不适合顶一个 对象的方法。

当我们使用箭头函数的时候,箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。

箭头函数是不能提升的,所以需要在使用之前定义。

使用 const 比使用 var 更安全,因为函数表达式始终是一个常量。

如果函数部分只是一个语句,则可以省略 return 关键字和大括号 {},这样做是一个比较好的习惯:

实例

const x = (x, y) => { return x * y }

this:

首先要知道this的是在代码执行的时候才能确定的,定义的时候不能确定,因为this是执行上下文的一部分,而执行上下文是在代执行的时候才能8定的。实际上this的最终指向的是那个调用它的对象。想理解this先看几个例子:

var a = {

name:'A',

fn: funcrion(){

console.log(this.name);

console.log(this);

}

}

a.fn();//this.name === 'A'; this===a

a.fn.call({name:'B'});//this.name===='B'; this==={name:'B'}

var fn1 = a.fn;

fn1();//this.name === undefined; this===window

通过上面的例子可以看出this的执行会有不同,主要集中在以下几种情况:1.作为构造函数执行,在构造函数中(上面例子未体现)2.作为对象属性执行,上述代码中的a.fn();3.作为普通函数执行,上述代码中fn1();4.用于call,apply,bind,上述代码中a.fn.call({name:'B'});

其中fn1() 的执行结果有些出乎意料,上文说过‘实际上this的最终指向的是那个调用它的对象’,fn1中this为什么指向了window?继续来看例子:

function a() {

var user = "例子";

console.log(this.user);//undefined

console.log(this);//window

}

a();

按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被Window对象所点出来的,下面的代码就可以证明:

function a() {

var user = "例子";

console.log(this.user);//undefined

console.log(this);//window

}

window.a();

继续看例子:

var o = {

user: "例子",

fn: function(){

console.log(this.user);//'例子'

console.log(this);// o

}

}

o.fn(); ==>window.o.fn()

o.fn();等价于window.o.fn(),但是this并没有指向window,而是指向O对象;是不是有些迷惑,继续看例子:

var o = {

a = 10;

b : {

a:12;

fn:function(){

console.log(this.a);//12

console.log(this);//b

}

}

}

o.b.fn();

同样属性都是对象o调用出来的,但同样this没有指向O。其实我们需要知道以下几点:

1.如果一个函数中有this,但是没有被上一级对象调用,那么this就指向window,严格模式下t'his将指向undefined;2.如果一个函数中有this,这个函数被上一级对象调用,那么this指向上一级对象;3.如果函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也是其上一级对象。(上面的例子中,将b对象的值注销既可以验证)

var o = {

a = 10;

b : {

//a:12;

fn:function(){

console.log(this.a);//undefined

console.log(this);//b

}

}

}

o.b.fn();

还有个特殊的例子:

var o = {

a = 10;

b : {

a:12;

fn:function(){

console.log(this.a);//undefined

console.log(this);//window;

}

}

}

var c = o.b.fn;

c();

this指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,这个例子中虽然函数fn是被对象b所引用,但是在将fn赋值给变量c的时候并没有执行所以最终指向的是window。

在构造函数中this指向也会不同:

function Fn(){

this.user = '例子';

}

var a = new Fn();

console.log(a.user)//'例子'

这里a可以调用到user的值,因为构造函数new关键字改变了this的指向,所以将this指向a。

当this遇到return时结果也会有差异,如下面的连个例子:

function Fn(){

this.user = '例子';

return {};

}

var a = new Fn();

console.log(a.user)//undefined

function Fn(){

this.user = '例子';

return 1;

}

var a = new Fn();

console.log(a.user)//'例子'

#####总结: 如果返回值是一个对象,那么this指向返回的这个对象,如果返回值不是一个对象,那么this还是指向函数的实例;null也是一个对象,但是null比较特殊,返回值是null,this还是指向函数的实例。

css实现两栏布局的总结:

两栏布局(左侧宽度固定,右侧自适应),在学习的过程中总结了几种方法:

方法一:float+margin-left

HTML部分

Left Side

我是左侧栏

Right Side

我是右侧栏

CSS部分

{

/清除默认格式/

margin:0;

padding:0;

}

.left{

width:200px;

background-color:red;

float:left;

}

.right{

background-color:green;

margin-left:200px;//等于左边栏的宽度

}


方法二:absolute+margin-leftCSS部分

{

margin:0;

padding:0;

}

.left{

width:100px;

background-color:red;

position:absolute;

}

.right{

background-color:green;

margin-left:100px;

}

方法三:float+BFC为左侧元素设置浮动后,左侧元素会因为浮动盖在右侧元素上,因此要将右侧元素变成BFC,BFC是一个独立的区域,不会让BFC外的元素对其内部造成干扰。当右侧元素变成一个BFC时它的元素边界会发生变化,会紧紧贴合左侧的元素。常见的右侧元素设置----overflow:hidden;

方法四:flex布局HTML部分

Left Side

我是左侧栏

Right Side

我是右侧栏

CSS设置:

{

/清除默认格式/

margin:0;

padding:0;

}

.box{

display:flex;

}

.box1{

}

.box2{

flex:1;

}

你可能感兴趣的:(2020-01-20)