function专题(一)

Write By Monkeyfly

以下内容均为原创,如需转载请注明出处。

前提

我们在刚开始学习JavaScript函数的时候,都是这样定义的:

function 函数名(参数列表...){
    //函数功能代码
}
函数名();

然后使用函数名()就可以调用之前定义好的函数,非常简单。

函数定义的不同写法:

//定义了一个匿名函数,然后将这个函数的引用保存在了变量fn中,所以fn就可以指向这个函数在内存中的空间
//注:因为JavaScript不允许直接访问对象在内存中的位置,即不能直接操作对象的内存空间。必须通过引用来访问。
var fn = function(){
    console.log(123);
}
fn();

上面的写法称为:函数表达式
或者这么写:

function sum(){
    var a = 1;
    var b = 2;
    return a+b; 
}
sum();

上面的写法才称之为:真正的函数定义

这两种写法的共同特点都是:先定义后调用。

但是在后来的学习过程中,却发现了如下这种写法:【即先调用后定义】

//自执行匿名函数
(function(){
    show();//函数调用
})();
//函数的定义
function show(){
    console.log("Hello World");
}

刚开始学习JavaScript基础教程的时候,并没有涉及过多的函数知识,只是学到了一些函数的基本用法和调用方式。再加上自己学习的进度比较慢,也没有接触过其他的写法,导致脑海中一直存在着一种错误的看法:“函数必须先定义后使用”,自此以后这种错误的想法便根深蒂固了。当我第一次看到这种写法时一直迷惑不解,也不知道为什么可以使用这种形式调用。

后来,随着学习的深入,渐渐明白了这种写法的本质。

接下来,我就来说说最近学到的有关函数的一些知识点。

示例1:

fn();
//这才是函数的定义
function fn(){
    console.log(111);
}

function fn(){
    console.log(111);
}
fn();

分析:
这两种写法都正确,都不会报错。
因为存在预解析这个阶段,所以像示例1中这种函数的第一种写法,可以先调用后定义。

示例2:

fn1();
//严格来说,这不能称之为函数的定义,应该称之为:函数表达式
var fn1 = function(){
    console.log(222);
}

分析:
(1)代码运行后会报错:

fn1();  //Uncaught TypeError: fn1 is not a function

(2)如果先调用fn1()的话,js解析器还不知道fn1这个值是什么。
(3)因为给fn1赋值的操作还在它的下面,此时就会认为这个值是undefined。所以,解析器就会认为fn1目前还不是一个函数。

示例1示例2中,这两种函数写法的区别:

  • function关键字定义的函数,前者:可以先调用后定义。
  • var变量引用的函数,后者:只能先定义后调用,否则会报错。

具体原因如下:

javascript代码运行分为两个阶段:

1.预解析
js解析器遇到js文件时,会先扫描一遍,即从头看到尾。
(这个过程相当于在饭店吃饭点菜时,要先浏览整个菜单看看都有哪些种类的饭菜,等浏览完毕后再执行点菜这个操作。)

2.执行

问:第一阶段主要做了哪些操作呢?
答:script标签里面的这些代码,js解析器会将里面的所有变量定义,函数定义,全部放在代码最前面的位置。
问:什么意思呢?
答:如下代码所示

var fn1;//变量的定义可以提前,但是赋值不能提前
var abc;


var fn1 = function(){
    console.log(222);
}

var abc = '123';

结论:
(1)预解析阶段 —— 把所有的函数定义提前,所有的变量声明提前,但是变量的赋值不提前。
(2)执行期 —— 按照代码的逻辑,从上到下执行。
例外:setTimeout()、setInterval()、ajax中的回调函数、事件中的函数需要触发执行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
优化这段代码% 读取第一组数据 imgfilename1 = 'C:\Users\86182\Desktop\tif\QB2013.dat'; data1 = read_data(imgfilename1); % 读取第二组数据 imgfilename2 = 'C:\Users\86182\Desktop\tif\SV2018.dat'; data2 = read_data(imgfilename2); % 显示Quickbird影像 im1 = data1(:, :, 2:4); im1 = uint8(im1); show_image(im1, 'Quickbird影像432波段显示', 1); % 显示高景影像 im2 = data2(:, :, 2:4); im2 = uint8(im2); show_image(im2, '高景影像432波段显示', 2); %NDVI计算结果图 X1=data1; im3=ndvi(X1); show_image(im3, '2013年(QB)NDVI专题图', 3); X2=data2; im4=ndvi(X2); show_image(im4, '2018年(SV)NDVI专题图', 4); function data = read_data(filename) %读取数据 data = multibandread(filename, [1989, 2126, 4], 'int16', 0, 'bsq', 'ieee-le', { 'Band', 'Direct', [1 4 3 2]}); %lines,samples,bands,hdr文件里查看 % 调整波段排列 %B=data(:,:,1); %G=data(:,:,2); %R=data(:,:,3); %C=data(:,:,4); %data=cat(4,B,C,R,G); % 将数据转换为0-255的整型用于显示 data_unit8 = uint8(data); for k = 1:4 data_k = double(data(:, :, k)); min_val = min(data_k, [], 'all'); max_val = max(data_k, [], 'all'); data_unit8(:, :, k) = uint8((data_k - min_val) / (max_val - min_val) * 255); end % 返回处理后的数据 data = data_unit8; end %ndvi计算 function data_ndvi(X) NIR = double(X(:,:,2));%近红外光谮带 red = double(X(:,:,3));%可见光红色光谱带 data_ndvi(:, :, k)=ndvi((NIR - red) ./ (NIR + red));%归一化 X=data_ndvi; end % 影像显示 function show_image(im, title_str, fig_num) figure(fig_num); imshow(im, [min(im(:)), max(im(:))]); title(title_str); end
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值